github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/wire/msgreject.go (about)

     1  // Copyright (c) 2014-2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package wire
     7  
     8  import (
     9  	"fmt"
    10  	"io"
    11  )
    12  
    13  // RejectCode represents a numeric value by which a remote peer indicates
    14  // why a message was rejected.
    15  type RejectCode uint8
    16  
    17  // These constants define the various supported reject codes.
    18  const (
    19  	RejectMalformed       RejectCode = 0x01
    20  	RejectInvalid         RejectCode = 0x10
    21  	RejectObsolete        RejectCode = 0x11
    22  	RejectDuplicate       RejectCode = 0x12
    23  	RejectNonstandard     RejectCode = 0x40
    24  	RejectDust            RejectCode = 0x41
    25  	RejectInsufficientFee RejectCode = 0x42
    26  	RejectCheckpoint      RejectCode = 0x43
    27  )
    28  
    29  // Map of reject codes back strings for pretty printing.
    30  var rejectCodeStrings = map[RejectCode]string{
    31  	RejectMalformed:       "REJECT_MALFORMED",
    32  	RejectInvalid:         "REJECT_INVALID",
    33  	RejectObsolete:        "REJECT_OBSOLETE",
    34  	RejectDuplicate:       "REJECT_DUPLICATE",
    35  	RejectNonstandard:     "REJECT_NONSTANDARD",
    36  	RejectDust:            "REJECT_DUST",
    37  	RejectInsufficientFee: "REJECT_INSUFFICIENTFEE",
    38  	RejectCheckpoint:      "REJECT_CHECKPOINT",
    39  }
    40  
    41  // String returns the RejectCode in human-readable form.
    42  func (code RejectCode) String() string {
    43  	if s, ok := rejectCodeStrings[code]; ok {
    44  		return s
    45  	}
    46  
    47  	return fmt.Sprintf("Unknown RejectCode (%d)", uint8(code))
    48  }
    49  
    50  // MsgReject implements the Message interface and represents a bitcoin reject
    51  // message.
    52  //
    53  // This message was not added until protocol version RejectVersion.
    54  type MsgReject struct {
    55  	// Cmd is the command for the message which was rejected such as
    56  	// as CmdBlock or CmdTx.  This can be obtained from the Command function
    57  	// of a Message.
    58  	Cmd string
    59  
    60  	// RejectCode is a code indicating why the command was rejected.  It
    61  	// is encoded as a uint8 on the wire.
    62  	Code RejectCode
    63  
    64  	// Reason is a human-readable string with specific details (over and
    65  	// above the reject code) about why the command was rejected.
    66  	Reason string
    67  
    68  	// Hash identifies a specific block or transaction that was rejected
    69  	// and therefore only applies the MsgBlock and MsgTx messages.
    70  	Hash ShaHash
    71  }
    72  
    73  // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
    74  // This is part of the Message interface implementation.
    75  func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
    76  	if pver < RejectVersion {
    77  		str := fmt.Sprintf("reject message invalid for protocol "+
    78  			"version %d", pver)
    79  		return messageError("MsgReject.BtcDecode", str)
    80  	}
    81  
    82  	// Command that was rejected.
    83  	cmd, err := ReadVarString(r, pver)
    84  	if err != nil {
    85  		return err
    86  	}
    87  	msg.Cmd = cmd
    88  
    89  	// Code indicating why the command was rejected.
    90  	err = readElement(r, &msg.Code)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	// Human readable string with specific details (over and above the
    96  	// reject code above) about why the command was rejected.
    97  	reason, err := ReadVarString(r, pver)
    98  	if err != nil {
    99  		return err
   100  	}
   101  	msg.Reason = reason
   102  
   103  	// CmdBlock and CmdTx messages have an additional hash field that
   104  	// identifies the specific block or transaction.
   105  	if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
   106  		err := readElement(r, &msg.Hash)
   107  		if err != nil {
   108  			return err
   109  		}
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
   116  // This is part of the Message interface implementation.
   117  func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error {
   118  	if pver < RejectVersion {
   119  		str := fmt.Sprintf("reject message invalid for protocol "+
   120  			"version %d", pver)
   121  		return messageError("MsgReject.BtcEncode", str)
   122  	}
   123  
   124  	// Command that was rejected.
   125  	err := WriteVarString(w, pver, msg.Cmd)
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	// Code indicating why the command was rejected.
   131  	err = writeElement(w, msg.Code)
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	// Human readable string with specific details (over and above the
   137  	// reject code above) about why the command was rejected.
   138  	err = WriteVarString(w, pver, msg.Reason)
   139  	if err != nil {
   140  		return err
   141  	}
   142  
   143  	// CmdBlock and CmdTx messages have an additional hash field that
   144  	// identifies the specific block or transaction.
   145  	if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
   146  		err := writeElement(w, &msg.Hash)
   147  		if err != nil {
   148  			return err
   149  		}
   150  	}
   151  
   152  	return nil
   153  }
   154  
   155  // Command returns the protocol command string for the message.  This is part
   156  // of the Message interface implementation.
   157  func (msg *MsgReject) Command() string {
   158  	return CmdReject
   159  }
   160  
   161  // MaxPayloadLength returns the maximum length the payload can be for the
   162  // receiver.  This is part of the Message interface implementation.
   163  func (msg *MsgReject) MaxPayloadLength(pver uint32) uint32 {
   164  	plen := uint32(0)
   165  	// The reject message did not exist before protocol version
   166  	// RejectVersion.
   167  	if pver >= RejectVersion {
   168  		// Unfortunately the bitcoin protocol does not enforce a sane
   169  		// limit on the length of the reason, so the max payload is the
   170  		// overall maximum message payload.
   171  		plen = MaxMessagePayload
   172  	}
   173  
   174  	return plen
   175  }
   176  
   177  // NewMsgReject returns a new bitcoin reject message that conforms to the
   178  // Message interface.  See MsgReject for details.
   179  func NewMsgReject(command string, code RejectCode, reason string) *MsgReject {
   180  	return &MsgReject{
   181  		Cmd:    command,
   182  		Code:   code,
   183  		Reason: reason,
   184  	}
   185  }