Support RelayTx param in ver message for 70001+.
This commit adds support for the version message RelayTx parameter for protocol version 70001+ as added by BIP0037.
This commit is contained in:
parent
8721348051
commit
e9a18fb14c
4 changed files with 186 additions and 10 deletions
26
common.go
26
common.go
|
@ -60,6 +60,19 @@ func readElement(r io.Reader, element interface{}) error {
|
|||
*e = binary.LittleEndian.Uint64(b)
|
||||
return nil
|
||||
|
||||
case *bool:
|
||||
b := scratch[0:1]
|
||||
_, err := io.ReadFull(r, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b[0] == 0x00 {
|
||||
*e = false
|
||||
} else {
|
||||
*e = true
|
||||
}
|
||||
return nil
|
||||
|
||||
// Message header checksum.
|
||||
case *[4]byte:
|
||||
_, err := io.ReadFull(r, e[:])
|
||||
|
@ -179,6 +192,19 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||
}
|
||||
return nil
|
||||
|
||||
case bool:
|
||||
b := scratch[0:1]
|
||||
if e == true {
|
||||
b[0] = 0x01
|
||||
} else {
|
||||
b[0] = 0x00
|
||||
}
|
||||
_, err := w.Write(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
// Message header checksum.
|
||||
case [4]byte:
|
||||
_, err := w.Write(e[:])
|
||||
|
|
|
@ -76,7 +76,7 @@ func TestMessage(t *testing.T) {
|
|||
btcnet btcwire.BitcoinNet // Network to use for wire encoding
|
||||
bytes int // Expected num bytes read/written
|
||||
}{
|
||||
{msgVersion, msgVersion, pver, btcwire.MainNet, 121},
|
||||
{msgVersion, msgVersion, pver, btcwire.MainNet, 122},
|
||||
{msgVerack, msgVerack, pver, btcwire.MainNet, 24},
|
||||
{msgGetAddr, msgGetAddr, pver, btcwire.MainNet, 24},
|
||||
{msgAddr, msgAddr, pver, btcwire.MainNet, 25},
|
||||
|
|
|
@ -49,6 +49,9 @@ type MsgVersion struct {
|
|||
|
||||
// Last block seen by the generator of the version message.
|
||||
LastBlock int32
|
||||
|
||||
// Announce transactions to peer.
|
||||
RelayTx bool
|
||||
}
|
||||
|
||||
// HasService returns whether the specified service is supported by the peer
|
||||
|
@ -129,6 +132,14 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
|
|||
}
|
||||
}
|
||||
|
||||
if pver >= BIP0037Version {
|
||||
err = readElement(r, &msg.RelayTx)
|
||||
if err != nil {
|
||||
// Optional
|
||||
msg.RelayTx = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -172,6 +183,12 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if pver >= BIP0037Version {
|
||||
err = writeElement(w, msg.RelayTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -189,8 +206,8 @@ func (msg *MsgVersion) MaxPayloadLength(pver uint32) uint32 {
|
|||
|
||||
// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes + remote
|
||||
// and local net addresses + nonce 8 bytes + length of user agent (varInt) +
|
||||
// max allowed useragent length + last block 4 bytes.
|
||||
return 32 + (maxNetAddressPayload(pver) * 2) + MaxVarIntPayload + MaxUserAgentLen
|
||||
// max allowed useragent length + last block 4 bytes + relay tx 1 byte.
|
||||
return 32 + (maxNetAddressPayload(pver) * 2) + MaxVarIntPayload + MaxUserAgentLen + 1
|
||||
}
|
||||
|
||||
// NewMsgVersion returns a new bitcoin version message that conforms to the
|
||||
|
@ -210,6 +227,7 @@ func NewMsgVersion(me *NetAddress, you *NetAddress, nonce uint64,
|
|||
Nonce: nonce,
|
||||
UserAgent: userAgent,
|
||||
LastBlock: lastBlock,
|
||||
RelayTx: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,10 @@ func TestVersion(t *testing.T) {
|
|||
t.Errorf("NewMsgVersion: wrong last block - got %v, want %v",
|
||||
msg.LastBlock, lastBlock)
|
||||
}
|
||||
if msg.RelayTx != true {
|
||||
t.Errorf("NewMsgVersion: relaytx is not true by default: - got %v, want %v",
|
||||
msg.RelayTx, true)
|
||||
}
|
||||
|
||||
// Version message should not have any services set by default.
|
||||
if msg.Services != 0 {
|
||||
|
@ -85,8 +89,8 @@ func TestVersion(t *testing.T) {
|
|||
// Ensure max payload is expected value.
|
||||
// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes +
|
||||
// remote and local net addresses + nonce 8 bytes + length of user agent
|
||||
// (varInt) + max allowed user agent length + last block 4 bytes.
|
||||
wantPayload := uint32(2101)
|
||||
// (varInt) + max allowed user agent length + last block 4 bytes + relay tx 1 byte.
|
||||
wantPayload := uint32(2102)
|
||||
maxPayload := msg.MaxPayloadLength(pver)
|
||||
if maxPayload != wantPayload {
|
||||
t.Errorf("MaxPayloadLength: wrong max payload length for "+
|
||||
|
@ -157,9 +161,9 @@ func TestVersionWire(t *testing.T) {
|
|||
}{
|
||||
// Latest protocol version.
|
||||
{
|
||||
baseVersion,
|
||||
baseVersion,
|
||||
baseVersionEncoded,
|
||||
baseVersion70001,
|
||||
baseVersion70001,
|
||||
baseVersion70001Encoded,
|
||||
btcwire.ProtocolVersion,
|
||||
},
|
||||
|
||||
|
@ -179,6 +183,14 @@ func TestVersionWire(t *testing.T) {
|
|||
btcwire.BIP0031Version,
|
||||
},
|
||||
|
||||
// Protocol version BIP0037Version.
|
||||
{
|
||||
baseVersion70001,
|
||||
baseVersion70001,
|
||||
baseVersion70001Encoded,
|
||||
btcwire.BIP0037Version,
|
||||
},
|
||||
|
||||
// Protocol version NetAddressTimeVersion.
|
||||
{
|
||||
baseVersion,
|
||||
|
@ -293,8 +305,10 @@ func TestVersionWireErrors(t *testing.T) {
|
|||
// Force error in user agent.
|
||||
{baseVersion, baseVersionEncoded, pver, 82, io.ErrShortWrite, io.ErrUnexpectedEOF},
|
||||
// Force error in last block.
|
||||
{baseVersion, baseVersionEncoded, pver, 98, io.ErrShortWrite, io.ErrUnexpectedEOF},
|
||||
// Force error due to user agent too big.
|
||||
{baseVersion, baseVersionEncoded, pver, 97, io.ErrShortWrite, io.EOF},
|
||||
// Force error in relay tx.
|
||||
{baseVersion70001, baseVersion70001Encoded, uint32(70001), 101, io.ErrShortWrite, io.EOF},
|
||||
// Force error due to user agent too big
|
||||
{exceedUAVer, exceedUAVerEncoded, pver, newLen, btcwireErr, btcwireErr},
|
||||
}
|
||||
|
||||
|
@ -442,6 +456,77 @@ func TestVersionOptionalFields(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestVersionRelayTx tests the MsgVersion RelayTx API
|
||||
func TestVersionRelayTx(t *testing.T) {
|
||||
// Create version message data.
|
||||
userAgent := "/btcdtest:0.0.1/"
|
||||
lastBlock := int32(234234)
|
||||
tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333}
|
||||
me, err := btcwire.NewNetAddress(tcpAddrMe, btcwire.SFNodeNetwork)
|
||||
if err != nil {
|
||||
t.Errorf("NewNetAddress: %v", err)
|
||||
}
|
||||
tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333}
|
||||
you, err := btcwire.NewNetAddress(tcpAddrYou, btcwire.SFNodeNetwork)
|
||||
if err != nil {
|
||||
t.Errorf("NewNetAddress: %v", err)
|
||||
}
|
||||
nonce, err := btcwire.RandomUint64()
|
||||
if err != nil {
|
||||
t.Errorf("RandomUint64: error generating nonce: %v", err)
|
||||
}
|
||||
|
||||
// Ensure we get the correct data back out.
|
||||
msg := btcwire.NewMsgVersion(me, you, nonce, userAgent, lastBlock)
|
||||
|
||||
// Explictly set RelayTx to false since true by default.
|
||||
msg.RelayTx = false
|
||||
|
||||
// Encode the message to wire format.
|
||||
var buf bytes.Buffer
|
||||
err = msg.BtcEncode(&buf, btcwire.BIP0037Version)
|
||||
if err != nil {
|
||||
t.Errorf("BtcEncode error %v", err)
|
||||
}
|
||||
b := buf.Bytes()
|
||||
if len(b) != 102 || b[101] != 0x00 {
|
||||
t.Errorf("Relay Tx is not false")
|
||||
}
|
||||
|
||||
wantBuf := []byte{
|
||||
0x71, 0x11, 0x01, 0x00, // Protocol version 70001
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
|
||||
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
|
||||
// AddrYou -- No timestamp for NetAddress in version message
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
|
||||
0x20, 0x8d, // Port 8333 in big-endian
|
||||
// AddrMe -- No timestamp for NetAddress in version message
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
|
||||
0x20, 0x8d, // Port 8333 in big-endian
|
||||
0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce
|
||||
0x10, // Varint for user agent length
|
||||
0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73,
|
||||
0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
|
||||
0xfa, 0x92, 0x03, 0x00, // Last block
|
||||
0x00, // Relay tx (false)
|
||||
}
|
||||
|
||||
// Decode the message from wire format.
|
||||
msg = &btcwire.MsgVersion{}
|
||||
rbuf := bytes.NewBuffer(wantBuf)
|
||||
err = msg.BtcDecode(rbuf, btcwire.BIP0037Version)
|
||||
if err != nil {
|
||||
t.Errorf("BtcDecode error %v", err)
|
||||
}
|
||||
if msg.RelayTx != false {
|
||||
t.Errorf("Relay Tx is not false")
|
||||
}
|
||||
}
|
||||
|
||||
// baseVersion is used in the various tests as a baseline MsgVersion.
|
||||
var baseVersion = &btcwire.MsgVersion{
|
||||
ProtocolVersion: 60002,
|
||||
|
@ -486,3 +571,50 @@ var baseVersionEncoded = []byte{
|
|||
0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
|
||||
0xfa, 0x92, 0x03, 0x00, // Last block
|
||||
}
|
||||
|
||||
// baseVersion70001 is used in the various tests as a baseline MsgVersion.
|
||||
var baseVersion70001 = &btcwire.MsgVersion{
|
||||
ProtocolVersion: 70001,
|
||||
Services: btcwire.SFNodeNetwork,
|
||||
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST)
|
||||
AddrYou: btcwire.NetAddress{
|
||||
Timestamp: time.Time{}, // Zero value -- no timestamp in version
|
||||
Services: btcwire.SFNodeNetwork,
|
||||
IP: net.ParseIP("192.168.0.1"),
|
||||
Port: 8333,
|
||||
},
|
||||
AddrMe: btcwire.NetAddress{
|
||||
Timestamp: time.Time{}, // Zero value -- no timestamp in version
|
||||
Services: btcwire.SFNodeNetwork,
|
||||
IP: net.ParseIP("127.0.0.1"),
|
||||
Port: 8333,
|
||||
},
|
||||
Nonce: 123123, // 0x1e0f3
|
||||
UserAgent: "/btcdtest:0.0.1/",
|
||||
LastBlock: 234234, // 0x392fa
|
||||
RelayTx: true,
|
||||
}
|
||||
|
||||
// baseVersion70001Encoded is the wire encoded bytes for baseVersion using protocol
|
||||
// version 70001 and is used in the various tests.
|
||||
var baseVersion70001Encoded = []byte{
|
||||
0x71, 0x11, 0x01, 0x00, // Protocol version 70001
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
|
||||
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
|
||||
// AddrYou -- No timestamp for NetAddress in version message
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
|
||||
0x20, 0x8d, // Port 8333 in big-endian
|
||||
// AddrMe -- No timestamp for NetAddress in version message
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
|
||||
0x20, 0x8d, // Port 8333 in big-endian
|
||||
0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce
|
||||
0x10, // Varint for user agent length
|
||||
0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73,
|
||||
0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
|
||||
0xfa, 0x92, 0x03, 0x00, // Last block
|
||||
0x01, // Relay tx
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue