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