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.
11 "github.com/btcsuite/btcd/chaincfg/chainhash"
14 // RejectCode represents a numeric value by which a remote peer indicates
15 // why a message was rejected.
18 // These constants define the various supported reject codes.
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
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",
42 // String returns the RejectCode in human-readable form.
43 func (code RejectCode) String() string {
44 if s, ok := rejectCodeStrings[code]; ok {
48 return fmt.Sprintf("Unknown RejectCode (%d)", uint8(code))
51 // MsgReject implements the Message interface and represents a bitcoin reject
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
61 // RejectCode is a code indicating why the command was rejected. It
62 // is encoded as a uint8 on the wire.
65 // Reason is a human-readable string with specific details (over and
66 // above the reject code) about why the command was rejected.
69 // Hash identifies a specific block or transaction that was rejected
70 // and therefore only applies the MsgBlock and MsgTx messages.
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 "+
80 return messageError("MsgReject.BtcDecode", str)
83 // Command that was rejected.
84 cmd, err := ReadVarString(r, pver)
90 // Code indicating why the command was rejected.
91 err = readElement(r, &msg.Code)
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)
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)
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 "+
122 return messageError("MsgReject.BtcEncode", str)
125 // Command that was rejected.
126 err := WriteVarString(w, pver, msg.Cmd)
131 // Code indicating why the command was rejected.
132 err = writeElement(w, msg.Code)
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)
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)
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 {
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 {
166 // The reject message did not exist before protocol version
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
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 {