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)
|
*e = binary.LittleEndian.Uint64(b)
|
||||||
return nil
|
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.
|
// Message header checksum.
|
||||||
case *[4]byte:
|
case *[4]byte:
|
||||||
_, err := io.ReadFull(r, e[:])
|
_, err := io.ReadFull(r, e[:])
|
||||||
|
@ -179,6 +192,19 @@ func writeElement(w io.Writer, element interface{}) error {
|
||||||
}
|
}
|
||||||
return nil
|
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.
|
// Message header checksum.
|
||||||
case [4]byte:
|
case [4]byte:
|
||||||
_, err := w.Write(e[:])
|
_, err := w.Write(e[:])
|
||||||
|
|
|
@ -76,7 +76,7 @@ func TestMessage(t *testing.T) {
|
||||||
btcnet btcwire.BitcoinNet // Network to use for wire encoding
|
btcnet btcwire.BitcoinNet // Network to use for wire encoding
|
||||||
bytes int // Expected num bytes read/written
|
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},
|
{msgVerack, msgVerack, pver, btcwire.MainNet, 24},
|
||||||
{msgGetAddr, msgGetAddr, pver, btcwire.MainNet, 24},
|
{msgGetAddr, msgGetAddr, pver, btcwire.MainNet, 24},
|
||||||
{msgAddr, msgAddr, pver, btcwire.MainNet, 25},
|
{msgAddr, msgAddr, pver, btcwire.MainNet, 25},
|
||||||
|
|
|
@ -49,6 +49,9 @@ type MsgVersion struct {
|
||||||
|
|
||||||
// Last block seen by the generator of the version message.
|
// Last block seen by the generator of the version message.
|
||||||
LastBlock int32
|
LastBlock int32
|
||||||
|
|
||||||
|
// Announce transactions to peer.
|
||||||
|
RelayTx bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasService returns whether the specified service is supported by the peer
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +183,12 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pver >= BIP0037Version {
|
||||||
|
err = writeElement(w, msg.RelayTx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +206,8 @@ func (msg *MsgVersion) MaxPayloadLength(pver uint32) uint32 {
|
||||||
|
|
||||||
// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes + remote
|
// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes + remote
|
||||||
// and local net addresses + nonce 8 bytes + length of user agent (varInt) +
|
// and local net addresses + nonce 8 bytes + length of user agent (varInt) +
|
||||||
// max allowed useragent length + last block 4 bytes.
|
// max allowed useragent length + last block 4 bytes + relay tx 1 byte.
|
||||||
return 32 + (maxNetAddressPayload(pver) * 2) + MaxVarIntPayload + MaxUserAgentLen
|
return 32 + (maxNetAddressPayload(pver) * 2) + MaxVarIntPayload + MaxUserAgentLen + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMsgVersion returns a new bitcoin version message that conforms to the
|
// 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,
|
Nonce: nonce,
|
||||||
UserAgent: userAgent,
|
UserAgent: userAgent,
|
||||||
LastBlock: lastBlock,
|
LastBlock: lastBlock,
|
||||||
|
RelayTx: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,10 @@ func TestVersion(t *testing.T) {
|
||||||
t.Errorf("NewMsgVersion: wrong last block - got %v, want %v",
|
t.Errorf("NewMsgVersion: wrong last block - got %v, want %v",
|
||||||
msg.LastBlock, lastBlock)
|
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.
|
// Version message should not have any services set by default.
|
||||||
if msg.Services != 0 {
|
if msg.Services != 0 {
|
||||||
|
@ -85,8 +89,8 @@ func TestVersion(t *testing.T) {
|
||||||
// Ensure max payload is expected value.
|
// Ensure max payload is expected value.
|
||||||
// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes +
|
// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes +
|
||||||
// remote and local net addresses + nonce 8 bytes + length of user agent
|
// remote and local net addresses + nonce 8 bytes + length of user agent
|
||||||
// (varInt) + max allowed user agent length + last block 4 bytes.
|
// (varInt) + max allowed user agent length + last block 4 bytes + relay tx 1 byte.
|
||||||
wantPayload := uint32(2101)
|
wantPayload := uint32(2102)
|
||||||
maxPayload := msg.MaxPayloadLength(pver)
|
maxPayload := msg.MaxPayloadLength(pver)
|
||||||
if maxPayload != wantPayload {
|
if maxPayload != wantPayload {
|
||||||
t.Errorf("MaxPayloadLength: wrong max payload length for "+
|
t.Errorf("MaxPayloadLength: wrong max payload length for "+
|
||||||
|
@ -157,9 +161,9 @@ func TestVersionWire(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
// Latest protocol version.
|
// Latest protocol version.
|
||||||
{
|
{
|
||||||
baseVersion,
|
baseVersion70001,
|
||||||
baseVersion,
|
baseVersion70001,
|
||||||
baseVersionEncoded,
|
baseVersion70001Encoded,
|
||||||
btcwire.ProtocolVersion,
|
btcwire.ProtocolVersion,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -179,6 +183,14 @@ func TestVersionWire(t *testing.T) {
|
||||||
btcwire.BIP0031Version,
|
btcwire.BIP0031Version,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Protocol version BIP0037Version.
|
||||||
|
{
|
||||||
|
baseVersion70001,
|
||||||
|
baseVersion70001,
|
||||||
|
baseVersion70001Encoded,
|
||||||
|
btcwire.BIP0037Version,
|
||||||
|
},
|
||||||
|
|
||||||
// Protocol version NetAddressTimeVersion.
|
// Protocol version NetAddressTimeVersion.
|
||||||
{
|
{
|
||||||
baseVersion,
|
baseVersion,
|
||||||
|
@ -293,8 +305,10 @@ func TestVersionWireErrors(t *testing.T) {
|
||||||
// Force error in user agent.
|
// Force error in user agent.
|
||||||
{baseVersion, baseVersionEncoded, pver, 82, io.ErrShortWrite, io.ErrUnexpectedEOF},
|
{baseVersion, baseVersionEncoded, pver, 82, io.ErrShortWrite, io.ErrUnexpectedEOF},
|
||||||
// Force error in last block.
|
// Force error in last block.
|
||||||
{baseVersion, baseVersionEncoded, pver, 98, io.ErrShortWrite, io.ErrUnexpectedEOF},
|
{baseVersion, baseVersionEncoded, pver, 97, io.ErrShortWrite, io.EOF},
|
||||||
// Force error due to user agent too big.
|
// 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},
|
{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.
|
// baseVersion is used in the various tests as a baseline MsgVersion.
|
||||||
var baseVersion = &btcwire.MsgVersion{
|
var baseVersion = &btcwire.MsgVersion{
|
||||||
ProtocolVersion: 60002,
|
ProtocolVersion: 60002,
|
||||||
|
@ -486,3 +571,50 @@ var baseVersionEncoded = []byte{
|
||||||
0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
|
0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
|
||||||
0xfa, 0x92, 0x03, 0x00, // Last block
|
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