diff --git a/pkg/consensus/prepare_request.go b/pkg/consensus/prepare_request.go index 02c374747..8f6f500cd 100644 --- a/pkg/consensus/prepare_request.go +++ b/pkg/consensus/prepare_request.go @@ -20,10 +20,7 @@ func (p *prepareRequest) EncodeBinary(w *io.BinWriter) { w.WriteLE(p.Timestamp) w.WriteLE(p.Nonce) w.WriteBE(p.NextConsensus[:]) - w.WriteVarUint(uint64(len(p.TransactionHashes))) - for i := range p.TransactionHashes { - w.WriteBE(p.TransactionHashes[i][:]) - } + w.WriteArray(p.TransactionHashes) p.MinerTransaction.EncodeBinary(w) } @@ -32,12 +29,6 @@ func (p *prepareRequest) DecodeBinary(r *io.BinReader) { r.ReadLE(&p.Timestamp) r.ReadLE(&p.Nonce) r.ReadBE(p.NextConsensus[:]) - - lenHashes := r.ReadVarUint() - p.TransactionHashes = make([]util.Uint256, lenHashes) - for i := range p.TransactionHashes { - r.ReadBE(p.TransactionHashes[i][:]) - } - + r.ReadArray(&p.TransactionHashes) p.MinerTransaction.DecodeBinary(r) } diff --git a/pkg/core/block.go b/pkg/core/block.go index 45bff104c..f02fb425f 100644 --- a/pkg/core/block.go +++ b/pkg/core/block.go @@ -135,10 +135,7 @@ func (b *Block) DecodeBinary(br *io.BinReader) { // Serializable interface. func (b *Block) EncodeBinary(bw *io.BinWriter) { b.BlockBase.EncodeBinary(bw) - bw.WriteVarUint(uint64(len(b.Transactions))) - for _, tx := range b.Transactions { - tx.EncodeBinary(bw) - } + bw.WriteArray(b.Transactions) } // Compare implements the queue Item interface. diff --git a/pkg/core/header_hash_list.go b/pkg/core/header_hash_list.go index 8f5bb6264..1a4b2fc05 100644 --- a/pkg/core/header_hash_list.go +++ b/pkg/core/header_hash_list.go @@ -58,10 +58,6 @@ func (l *HeaderHashList) Slice(start, end int) []util.Uint256 { // WriteTo writes n underlying hashes to the given BinWriter // starting from start. func (l *HeaderHashList) Write(bw *io.BinWriter, start, n int) error { - bw.WriteVarUint(uint64(n)) - hashes := l.Slice(start, start+n) - for _, hash := range hashes { - bw.WriteLE(hash) - } + bw.WriteArray(l.Slice(start, start+n)) return bw.Err } diff --git a/pkg/io/size_test.go b/pkg/io/size_test.go index 9b45b6311..4e397894c 100644 --- a/pkg/io/size_test.go +++ b/pkg/io/size_test.go @@ -1,9 +1,10 @@ -package io +package io_test import ( "fmt" "testing" + "github.com/CityOfZion/neo-go/pkg/io" "github.com/CityOfZion/neo-go/pkg/util" "github.com/stretchr/testify/assert" ) @@ -13,18 +14,18 @@ type smthSerializable struct { some [42]byte } -func (*smthSerializable) DecodeBinary(*BinReader) {} +func (*smthSerializable) DecodeBinary(*io.BinReader) {} -func (ss *smthSerializable) EncodeBinary(bw *BinWriter) { +func (ss *smthSerializable) EncodeBinary(bw *io.BinWriter) { bw.WriteLE(ss.some) } // Mock structure that gives error in EncodeBinary(). type smthNotReallySerializable struct{} -func (*smthNotReallySerializable) DecodeBinary(*BinReader) {} +func (*smthNotReallySerializable) DecodeBinary(*io.BinReader) {} -func (*smthNotReallySerializable) EncodeBinary(bw *BinWriter) { +func (*smthNotReallySerializable) EncodeBinary(bw *io.BinWriter) { bw.Err = fmt.Errorf("smth bad happened in smthNotReallySerializable") } @@ -182,7 +183,7 @@ func TestVarSize(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("run: %s", tc.name), func(t *testing.T) { - result := GetVarSize(tc.variable) + result := io.GetVarSize(tc.variable) assert.Equal(t, tc.expected, result) }) } @@ -194,7 +195,7 @@ func panicVarSize(t *testing.T, v interface{}) { assert.NotNil(t, r) }() - _ = GetVarSize(v) + _ = io.GetVarSize(v) // this should never execute assert.Nil(t, t) } diff --git a/pkg/network/payload/getblocks.go b/pkg/network/payload/getblocks.go index 12255fcae..8701a1df0 100644 --- a/pkg/network/payload/getblocks.go +++ b/pkg/network/payload/getblocks.go @@ -23,16 +23,12 @@ func NewGetBlocks(start []util.Uint256, stop util.Uint256) *GetBlocks { // DecodeBinary implements Serializable interface. func (p *GetBlocks) DecodeBinary(br *io.BinReader) { - lenStart := br.ReadVarUint() - p.HashStart = make([]util.Uint256, lenStart) - - br.ReadLE(&p.HashStart) + br.ReadArray(&p.HashStart) br.ReadLE(&p.HashStop) } // EncodeBinary implements Serializable interface. func (p *GetBlocks) EncodeBinary(bw *io.BinWriter) { - bw.WriteVarUint(uint64(len(p.HashStart))) - bw.WriteLE(p.HashStart) + bw.WriteArray(p.HashStart) bw.WriteLE(p.HashStop) } diff --git a/pkg/network/payload/inventory.go b/pkg/network/payload/inventory.go index ccefe8527..036aa0279 100644 --- a/pkg/network/payload/inventory.go +++ b/pkg/network/payload/inventory.go @@ -57,21 +57,11 @@ func NewInventory(typ InventoryType, hashes []util.Uint256) *Inventory { // DecodeBinary implements Serializable interface. func (p *Inventory) DecodeBinary(br *io.BinReader) { br.ReadLE(&p.Type) - - listLen := br.ReadVarUint() - p.Hashes = make([]util.Uint256, listLen) - for i := 0; i < int(listLen); i++ { - br.ReadLE(&p.Hashes[i]) - } + br.ReadArray(&p.Hashes) } // EncodeBinary implements Serializable interface. func (p *Inventory) EncodeBinary(bw *io.BinWriter) { bw.WriteLE(p.Type) - - listLen := len(p.Hashes) - bw.WriteVarUint(uint64(listLen)) - for i := 0; i < listLen; i++ { - bw.WriteLE(p.Hashes[i]) - } + bw.WriteArray(p.Hashes) } diff --git a/pkg/network/payload/merkleblock.go b/pkg/network/payload/merkleblock.go index 996f32431..dad96f305 100644 --- a/pkg/network/payload/merkleblock.go +++ b/pkg/network/payload/merkleblock.go @@ -20,11 +20,7 @@ func (m *MerkleBlock) DecodeBinary(br *io.BinReader) { m.BlockBase.DecodeBinary(br) m.TxCount = int(br.ReadVarUint()) - n := br.ReadVarUint() - m.Hashes = make([]util.Uint256, n) - for i := 0; i < len(m.Hashes); i++ { - br.ReadLE(&m.Hashes[i]) - } + br.ReadArray(&m.Hashes) m.Flags = br.ReadBytes() } @@ -34,9 +30,6 @@ func (m *MerkleBlock) EncodeBinary(bw *io.BinWriter) { m.BlockBase.EncodeBinary(bw) bw.WriteVarUint(uint64(m.TxCount)) - bw.WriteVarUint(uint64(len(m.Hashes))) - for i := 0; i < len(m.Hashes); i++ { - bw.WriteLE(m.Hashes[i]) - } + bw.WriteArray(m.Hashes) bw.WriteBytes(m.Flags) } diff --git a/pkg/util/uint256.go b/pkg/util/uint256.go index 40dfdb93a..76d69c468 100644 --- a/pkg/util/uint256.go +++ b/pkg/util/uint256.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" "strings" + + "github.com/CityOfZion/neo-go/pkg/io" ) // Uint256Size is the size of Uint256 in bytes. @@ -93,3 +95,13 @@ func (u Uint256) MarshalJSON() ([]byte, error) { // -1 implies u < other. // 0 implies u = other. func (u Uint256) CompareTo(other Uint256) int { return bytes.Compare(u[:], other[:]) } + +// EncodeBinary implements io.Serializable interface. +func (u Uint256) EncodeBinary(w *io.BinWriter) { + w.WriteBE(u) +} + +// DecodeBinary implements io.Serializable interface. +func (u *Uint256) DecodeBinary(r *io.BinReader) { + r.ReadBE(u[:]) +} diff --git a/pkg/util/uint256_test.go b/pkg/util/uint256_test.go index 59fff1838..975edec9f 100644 --- a/pkg/util/uint256_test.go +++ b/pkg/util/uint256_test.go @@ -4,7 +4,9 @@ import ( "encoding/hex" "testing" + "github.com/CityOfZion/neo-go/pkg/io" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestUint256UnmarshalJSON(t *testing.T) { @@ -75,3 +77,19 @@ func TestUInt256Equals(t *testing.T) { t.Fatalf("%s and %s must be equal", ua, ua) } } + +func TestUint256_Serializable(t *testing.T) { + a := Uint256{ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + } + + w := io.NewBufBinWriter() + a.EncodeBinary(w.BinWriter) + require.NoError(t, w.Err) + + var b Uint256 + r := io.NewBinReaderFromBuf(w.Bytes()) + b.DecodeBinary(r) + require.Equal(t, a, b) +}