Files
btc_wire_proto/spec/btc_wire_proto_spec.rb

293 lines
7.9 KiB
Ruby
Raw Normal View History

2011-06-04 22:53:33 +01:00
require 'spec_helper'
require 'btc_wire_proto'
# Fixtures data. Taken from: https://en.bitcoin.it/wiki/Protocol_specification
include ::BtcWireProto
describe ::BtcWireProto do
# Payload fragments
describe ServicesMask do
it "should have node_network set to false when its bit is 0" do
s = ServicesMask::read("\x00" * 8) # All 64 bits unset
s.node_network.should == 0
s = ServicesMask::read(binary(%w{01 00 00 00 00 00 00 00}))
s.node_network.should == 1
end
end
describe NetAddr do
it "should have all fields set to 0 when the input data is all zeroes" do
na = NetAddr::read("\x00" * 26)
na.services.node_network.should == 0
na.ip.to_u128.should == 0
na.port.should == 0
end
it "Should allow the Ip field to be set with Ruby native types" do
na = NetAddr::read("\x00" * 26)
mip = IPAddress("::ffff:0.0.0.1")
na.ip = mip
na.ip.to_u128.should == mip.to_u128
end
it "should have the fields set appropriately when fed binary data" do
na = NetAddr::read(
binary(%w{
01 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 FF FF 0A 00 00 01 20 8D
})
)
na.services.node_network.should == 1
na.ip.to_s.should == "::ffff:10.0.0.1"
na.port.should == 8333
end
end
describe TimestampedNetAddr do
it "should leverage NetAddr" do
tna = TimestampedNetAddr::read("\x00" * 30)
tna.net_addr.class.should == BtcWireProto::NetAddr
end
it "should have all fields set to 0 when the input data is all zeroes" do
tna = TimestampedNetAddr::read("\x00" * 30)
tna.timestamp.should == 0
end
it "should have the fields set appropriately when fed binary data" do
tna = TimestampedNetAddr::read(
binary(%w{
E2 15 10 4D 01 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 FF FF 0A 00 00 01 20 8D
})
)
tna.timestamp.should == 1292899810
tna.net_addr.services.node_network.should == 1
tna.net_addr.ip.to_s.should == "::ffff:10.0.0.1"
tna.net_addr.port.should == 8333
end
end
describe VarInt do
it "should hold numbers < 0x00000000 in nine bytes" do
bin_minus_1 = "\xff" + "\x00\x00\x00\x00" + "\x01\x00\x00\x00"
a = VarInt::read(bin_minus_1)
a.should == -1
a.num_bytes.should == 9
a.to_binary_s.should == bin_minus_1
a = VarInt::read("\xff" * 9)
a.should == -(2**64 - 1)
a.num_bytes.should == 9
a.to_binary_s.should == "\xff" * 9
end
it "should hold numbers >= 0x00000000 and < 0x000000fd in one byte" do
a = VarInt::read("\x00")
a.should == 0x00
a.num_bytes.should == 1
a.to_binary_s.should == "\x00"
a = VarInt::read("\xFC")
a.should == 0xFC
a.num_bytes.should == 1
a.to_binary_s.should == "\xFC"
end
it "should hold numbers >= 0x000000fd and < 0x00010000 in three bytes" do
a = VarInt::read("\xFD\xFD\x00")
a.should == 0xFD
a.num_bytes.should == 3
a.to_binary_s.should == "\xFD\xFD\x00"
a = VarInt::read("\xFD\xFF\xFF")
a.should == 0xFFFF
a.num_bytes.should == 3
a.to_binary_s.should == "\xFD\xFF\xFF"
end
it "should hold numbers >= 0x00010000 and < 0xffffffff in five bytes" do
a = VarInt::read("\xFE\x00\x00\x01\x00")
a.should == 0x10000
a.num_bytes.should == 5
a.to_binary_s.should == "\xFE\x00\x00\x01\x00"
a = VarInt::read("\xFE\xFF\xFF\xFF\xFF")
a.should == 0xFFFFFFFF
a.num_bytes.should == 5
a.to_binary_s.should == "\xFE\xFF\xFF\xFF\xFF"
end
end
describe VarStr do
it "should store string length in a var_int" do
a = VarStr::read("\x04abcd")
a.should == "abcd"
a.num_bytes.should == 5
a.to_binary_s.should == "\x04abcd"
a = VarStr::read("\xFD\xFF\xFF" + "A" * 0xFFFF)
a.should == "A" * 0xFFFF
a.num_bytes.should == 0xFFFF + 3
a.to_binary_s.should == "\xFD\xFF\xFF" + "A" * 0xFFFF
end
end
describe InventoryVector do
end
describe Sha256 do
end
describe TransactionIn do
end
describe TransactionOut do
end
describe BlockHdr do
end
# Payloads
describe Version do
it "should interpret binary data correctly" do
ver = Version::read(binary(%w{
9C 7C 00 00 01 00 00 00 00 00 00 00 E6 15 10 4D 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF
0A 00 00 01 DA F6 01 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 FF FF 0A 00 00 02 20 8D DD 9D 20 2C 3A B4 57 13
00 55 81 01 00
}))
ver.version.should == 31900
ver.services.node_network.should == 1
ver.timestamp.should == 1292899814
ver.addr_me.class.should == NetAddr
ver.addr_you.class.should == NetAddr
ver.nonce.should == 0x1357B43A2C209DDD
ver.sub_version.should == ""
ver.start_height.should == 98645
end
it "should exclude some fields by version" do
v = Version::read([1].pack("V") + "\x00" * 42)
v.num_bytes.should == 46
v = Version::read([106].pack("V") + "\x00" * 77)
v.num_bytes.should == 81
v = Version::read([209].pack("V") + "\x00" * 81)
v.num_bytes.should == 85
end
end
describe AddrPre31402 do
end
describe AddrFrom31402 do
end
describe Inventory do
end
describe BlockSpec do
end
describe Transaction do
end
describe Block do
end
describe Headers do
end
describe CheckOrder do
end
describe SubmitOrder do
end
describe Reply do
end
describe Alert do
end
# Messages
describe MessageHdr do
end
describe Message do
context "Version message" do
it "should have a Version payload" do
m = Message::new(:header => {:command => 'version'})
m.payload.selection.should == "version"
end
it "should have a :version command symbol" do
m = Message::new(:header => {:command => 'version'})
m.cmd_sym.should == :version
end
2011-06-04 22:53:33 +01:00
it "should parse binary data correctly" do
m = Message::read(binary(%w{
F9 BE B4 D9 76 65 72 73 69 6F 6E 00 00 00 00 00 55 00 00
00 9C 7C 00 00 01 00 00 00 00 00 00 00 E6 15 10 4D 00 00
00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 FF FF 0A 00 00 01 DA F6 01 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 FF FF 0A 00 00 02 20 8D DD 9D 20
2C 3A B4 57 13 00 55 81 01 00
}))
m.header.magic.should == BtcWireProto::NETWORKS[:main]
m.header.command.should == "version\x00\x00\x00\x00\x00"
m.header.payload_len.should == 85
m.header.has_parameter?(:checksum).should be_false
m.payload.version.should == 31900
m.payload.services.node_network.should == 1
m.payload.timestamp.should == 1292899814
m.payload.addr_me.class.should == NetAddr
m.payload.addr_you.class.should == NetAddr
m.payload.nonce.should == 0x1357B43A2C209DDD
m.payload.sub_version.should == ""
m.payload.start_height.should == 98645
end
end
context "Verack message" do
it "should have no payload" do
m = Message.new(:header => {:command => "verack"})
m.payload.selection.should == "null"
end
it "should have a :verack command symbol" do
m = Message.new(:header => {:command => "verack"})
m.cmd_sym.should == :verack
end
2011-06-04 22:53:33 +01:00
it "should parse the binary data correctly" do
m = Message::read(binary(%w{
F9 BE B4 D9 76 65 72 61 63 6B 00 00 00 00 00 00 00 00 00 00
}))
m.header.magic.should == BtcWireProto::NETWORKS[:main]
m.header.command.should == "verack\x00\x00\x00\x00\x00\x00"
m.header.payload_len.should == 0
m.header.has_parameter?(:chcksum).should be_false
end
end
end
end