kaspad/wire/msgreject.go
Ori Newman e0aac68759
[NOD-1128] Convert message type to uint32 (#799)
* [NOD-1128] Change message command to uint32

* [NOD-1128] Don't use iota

* [NOD-1128] Remove redundant line
2020-07-16 17:11:05 +03:00

173 lines
5.0 KiB
Go

// Copyright (c) 2014-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/kaspanet/kaspad/util/daghash"
)
// RejectCode represents a numeric value by which a remote peer indicates
// why a message was rejected.
type RejectCode uint8
// These constants define the various supported reject codes.
const (
RejectMalformed RejectCode = 0x01
RejectInvalid RejectCode = 0x10
RejectObsolete RejectCode = 0x11
RejectDuplicate RejectCode = 0x12
RejectNotRequested RejectCode = 0x13
RejectNonstandard RejectCode = 0x40
RejectDust RejectCode = 0x41
RejectInsufficientFee RejectCode = 0x42
RejectFinality RejectCode = 0x43
RejectDifficulty RejectCode = 0x44
)
// Map of reject codes back strings for pretty printing.
var rejectCodeStrings = map[RejectCode]string{
RejectMalformed: "REJECT_MALFORMED",
RejectInvalid: "REJECT_INVALID",
RejectObsolete: "REJECT_OBSOLETE",
RejectDuplicate: "REJECT_DUPLICATE",
RejectNonstandard: "REJECT_NONSTANDARD",
RejectDust: "REJECT_DUST",
RejectInsufficientFee: "REJECT_INSUFFICIENTFEE",
RejectFinality: "REJECT_FINALITY",
RejectDifficulty: "REJECT_DIFFICULTY",
RejectNotRequested: "REJECT_NOTREQUESTED",
}
// String returns the RejectCode in human-readable form.
func (code RejectCode) String() string {
if s, ok := rejectCodeStrings[code]; ok {
return s
}
return fmt.Sprintf("Unknown RejectCode (%d)", uint8(code))
}
// MsgReject implements the Message interface and represents a kaspa reject
// message.
//
// This message was not added until protocol version RejectVersion.
type MsgReject struct {
// Cmd is the command for the message which was rejected such as
// as CmdBlock or CmdTx. This can be obtained from the Command function
// of a Message.
Cmd MessageCommand
// RejectCode is a code indicating why the command was rejected. It
// is encoded as a uint8 on the wire.
Code RejectCode
// Reason is a human-readable string with specific details (over and
// above the reject code) about why the command was rejected.
Reason string
// Hash identifies a specific block or transaction that was rejected
// and therefore only applies the MsgBlock and MsgTx messages.
Hash *daghash.Hash
}
// KaspaDecode decodes r using the kaspa protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgReject) KaspaDecode(r io.Reader, pver uint32) error {
// Command that was rejected.
err := ReadElement(r, &msg.Cmd)
if err != nil {
return err
}
// Code indicating why the command was rejected.
err = ReadElement(r, &msg.Code)
if err != nil {
return err
}
// Human readable string with specific details (over and above the
// reject code above) about why the command was rejected.
reason, err := ReadVarString(r, pver)
if err != nil {
return err
}
msg.Reason = reason
// CmdBlock and CmdTx messages have an additional hash field that
// identifies the specific block or transaction.
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
msg.Hash = &daghash.Hash{}
err := ReadElement(r, msg.Hash)
if err != nil {
return err
}
}
return nil
}
// KaspaEncode encodes the receiver to w using the kaspa protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgReject) KaspaEncode(w io.Writer, pver uint32) error {
// Command that was rejected.
err := WriteElement(w, msg.Cmd)
if err != nil {
return err
}
// Code indicating why the command was rejected.
err = WriteElement(w, msg.Code)
if err != nil {
return err
}
// Human readable string with specific details (over and above the
// reject code above) about why the command was rejected.
err = WriteVarString(w, msg.Reason)
if err != nil {
return err
}
// CmdBlock and CmdTx messages have an additional hash field that
// identifies the specific block or transaction.
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
err := WriteElement(w, msg.Hash)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgReject) Command() MessageCommand {
return CmdReject
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgReject) MaxPayloadLength(pver uint32) uint32 {
// Unfortunately the kaspa protocol does not enforce a sane
// limit on the length of the reason, so the max payload is the
// overall maximum message payload.
return uint32(MaxMessagePayload)
}
// NewMsgReject returns a new kaspa reject message that conforms to the
// Message interface. See MsgReject for details.
func NewMsgReject(command MessageCommand, code RejectCode, reason string) *MsgReject {
return &MsgReject{
Cmd: command,
Code: code,
Reason: reason,
Hash: &daghash.ZeroHash,
}
}