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 }