From fccb0085941ec67351435190e1632b44c640ddfe Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 6 Dec 2019 18:37:46 +0300 Subject: [PATCH] io: implement ReadBytes() --- pkg/consensus/commit.go | 2 +- pkg/consensus/payload.go | 2 +- pkg/consensus/prepare_request.go | 2 +- pkg/consensus/prepare_response.go | 2 +- pkg/consensus/recovery_message.go | 4 ++-- pkg/core/account_state.go | 4 ++-- pkg/core/asset_state.go | 8 ++++---- pkg/core/block_base.go | 12 ++++++------ pkg/core/header.go | 6 +++--- pkg/core/notification_event.go | 4 ++-- pkg/core/spent_coin_state.go | 2 +- pkg/core/transaction/attribute.go | 4 ++-- pkg/core/transaction/input.go | 2 +- pkg/core/transaction/output.go | 4 ++-- pkg/core/transaction/register.go | 2 +- pkg/crypto/keys/publickey.go | 6 +++--- pkg/io/binaryReader.go | 11 ++++++++++- pkg/io/binaryrw_test.go | 25 +++++++++++++++++++++++++ pkg/network/message.go | 2 +- pkg/network/payload/address.go | 2 +- pkg/network/payload/getblocks.go | 2 +- pkg/util/uint256.go | 2 +- 22 files changed, 72 insertions(+), 38 deletions(-) diff --git a/pkg/consensus/commit.go b/pkg/consensus/commit.go index da20be00f..2a3c39445 100644 --- a/pkg/consensus/commit.go +++ b/pkg/consensus/commit.go @@ -23,7 +23,7 @@ func (c *commit) EncodeBinary(w *io.BinWriter) { // DecodeBinary implements io.Serializable interface. func (c *commit) DecodeBinary(r *io.BinReader) { - r.ReadBE(&c.signature) + r.ReadBytes(c.signature[:]) } // Signature implements payload.Commit interface. diff --git a/pkg/consensus/payload.go b/pkg/consensus/payload.go index 80d73e2c7..f8f635314 100644 --- a/pkg/consensus/payload.go +++ b/pkg/consensus/payload.go @@ -212,7 +212,7 @@ func (p *Payload) Verify() bool { // DecodeBinaryUnsigned reads payload from w excluding signature. func (p *Payload) DecodeBinaryUnsigned(r *io.BinReader) { r.ReadLE(&p.version) - r.ReadBE(p.prevHash[:]) + r.ReadBytes(p.prevHash[:]) r.ReadLE(&p.height) r.ReadLE(&p.validatorIndex) r.ReadLE(&p.timestamp) diff --git a/pkg/consensus/prepare_request.go b/pkg/consensus/prepare_request.go index ef98e6512..a8ab4436f 100644 --- a/pkg/consensus/prepare_request.go +++ b/pkg/consensus/prepare_request.go @@ -31,7 +31,7 @@ func (p *prepareRequest) EncodeBinary(w *io.BinWriter) { func (p *prepareRequest) DecodeBinary(r *io.BinReader) { r.ReadLE(&p.timestamp) r.ReadLE(&p.nonce) - r.ReadBE(p.nextConsensus[:]) + r.ReadBytes(p.nextConsensus[:]) r.ReadArray(&p.transactionHashes) p.minerTx.DecodeBinary(r) } diff --git a/pkg/consensus/prepare_response.go b/pkg/consensus/prepare_response.go index 760b9475c..08bbaac72 100644 --- a/pkg/consensus/prepare_response.go +++ b/pkg/consensus/prepare_response.go @@ -20,7 +20,7 @@ func (p *prepareResponse) EncodeBinary(w *io.BinWriter) { // DecodeBinary implements io.Serializable interface. func (p *prepareResponse) DecodeBinary(r *io.BinReader) { - r.ReadBE(p.preparationHash[:]) + r.ReadBytes(p.preparationHash[:]) } // PreparationHash implements payload.PrepareResponse interface. diff --git a/pkg/consensus/recovery_message.go b/pkg/consensus/recovery_message.go index 4e6094f66..365e1917f 100644 --- a/pkg/consensus/recovery_message.go +++ b/pkg/consensus/recovery_message.go @@ -54,7 +54,7 @@ func (m *recoveryMessage) DecodeBinary(r *io.BinReader) { if l != 0 { if l == util.Uint256Size { m.preparationHash = new(util.Uint256) - r.ReadBE(m.preparationHash[:]) + r.ReadBytes(m.preparationHash[:]) } else { r.Err = errors.New("invalid data") } @@ -108,7 +108,7 @@ func (p *changeViewCompact) EncodeBinary(w *io.BinWriter) { func (p *commitCompact) DecodeBinary(r *io.BinReader) { r.ReadLE(&p.ViewNumber) r.ReadLE(&p.ValidatorIndex) - r.ReadBE(p.Signature[:]) + r.ReadBytes(p.Signature[:]) p.InvocationScript = r.ReadVarBytes() } diff --git a/pkg/core/account_state.go b/pkg/core/account_state.go index abec81994..daf07b805 100644 --- a/pkg/core/account_state.go +++ b/pkg/core/account_state.go @@ -103,7 +103,7 @@ func NewAccountState(scriptHash util.Uint160) *AccountState { // DecodeBinary decodes AccountState from the given BinReader. func (s *AccountState) DecodeBinary(br *io.BinReader) { br.ReadLE(&s.Version) - br.ReadLE(&s.ScriptHash) + br.ReadBytes(s.ScriptHash[:]) br.ReadLE(&s.IsFrozen) br.ReadArray(&s.Votes) @@ -111,7 +111,7 @@ func (s *AccountState) DecodeBinary(br *io.BinReader) { lenBalances := br.ReadVarUint() for i := 0; i < int(lenBalances); i++ { key := util.Uint256{} - br.ReadLE(&key) + br.ReadBytes(key[:]) ubs := make([]UnspentBalance, 0) br.ReadArray(&ubs) s.Balances[key] = ubs diff --git a/pkg/core/asset_state.go b/pkg/core/asset_state.go index 00cb7492a..fc0fe09e7 100644 --- a/pkg/core/asset_state.go +++ b/pkg/core/asset_state.go @@ -52,7 +52,7 @@ type AssetState struct { // DecodeBinary implements Serializable interface. func (a *AssetState) DecodeBinary(br *io.BinReader) { - br.ReadLE(&a.ID) + br.ReadBytes(a.ID[:]) br.ReadLE(&a.AssetType) a.Name = br.ReadString() @@ -61,12 +61,12 @@ func (a *AssetState) DecodeBinary(br *io.BinReader) { br.ReadLE(&a.Available) br.ReadLE(&a.Precision) br.ReadLE(&a.FeeMode) - br.ReadLE(&a.FeeAddress) + br.ReadBytes(a.FeeAddress[:]) a.Owner = &keys.PublicKey{} a.Owner.DecodeBinary(br) - br.ReadLE(&a.Admin) - br.ReadLE(&a.Issuer) + br.ReadBytes(a.Admin[:]) + br.ReadBytes(a.Issuer[:]) br.ReadLE(&a.Expiration) br.ReadLE(&a.IsFrozen) } diff --git a/pkg/core/block_base.go b/pkg/core/block_base.go index e4a4bd64f..7ca235ae2 100644 --- a/pkg/core/block_base.go +++ b/pkg/core/block_base.go @@ -73,9 +73,9 @@ func (b *BlockBase) VerificationHash() util.Uint256 { func (b *BlockBase) DecodeBinary(br *io.BinReader) { b.decodeHashableFields(br) - var padding uint8 - br.ReadLE(&padding) - if padding != 1 { + padding := []byte{0} + br.ReadBytes(padding) + if padding[0] != 1 { br.Err = fmt.Errorf("format error: padding must equal 1 got %d", padding) return } @@ -128,12 +128,12 @@ func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) { // see Hash() for more information about the fields. func (b *BlockBase) decodeHashableFields(br *io.BinReader) { br.ReadLE(&b.Version) - br.ReadLE(&b.PrevHash) - br.ReadLE(&b.MerkleRoot) + br.ReadBytes(b.PrevHash[:]) + br.ReadBytes(b.MerkleRoot[:]) br.ReadLE(&b.Timestamp) br.ReadLE(&b.Index) br.ReadLE(&b.ConsensusData) - br.ReadLE(&b.NextConsensus) + br.ReadBytes(b.NextConsensus[:]) // Make the hash of the block here so we dont need to do this // again. diff --git a/pkg/core/header.go b/pkg/core/header.go index e21ce70ed..e3bf50824 100644 --- a/pkg/core/header.go +++ b/pkg/core/header.go @@ -18,10 +18,10 @@ type Header struct { func (h *Header) DecodeBinary(r *io.BinReader) { h.BlockBase.DecodeBinary(r) - var padding uint8 - r.ReadLE(&padding) + padding := []byte{0} + r.ReadBytes(padding) - if padding != 0 { + if padding[0] != 0 { r.Err = fmt.Errorf("format error: padding must equal 0 got %d", padding) } } diff --git a/pkg/core/notification_event.go b/pkg/core/notification_event.go index db30b1cfd..fc1c6e727 100644 --- a/pkg/core/notification_event.go +++ b/pkg/core/notification_event.go @@ -63,7 +63,7 @@ func (ne NotificationEvent) EncodeBinary(w *io.BinWriter) { // DecodeBinary implements the Serializable interface. func (ne *NotificationEvent) DecodeBinary(r *io.BinReader) { - r.ReadLE(&ne.ScriptHash) + r.ReadBytes(ne.ScriptHash[:]) ne.Item = vm.DecodeBinaryStackItem(r) } @@ -75,6 +75,6 @@ func (aer *AppExecResult) EncodeBinary(w *io.BinWriter) { // DecodeBinary implements the Serializable interface. func (aer *AppExecResult) DecodeBinary(r *io.BinReader) { - r.ReadLE(&aer.TxHash) + r.ReadBytes(aer.TxHash[:]) r.ReadArray(&aer.Events) } diff --git a/pkg/core/spent_coin_state.go b/pkg/core/spent_coin_state.go index c3fe07e0f..f298ff9f5 100644 --- a/pkg/core/spent_coin_state.go +++ b/pkg/core/spent_coin_state.go @@ -75,7 +75,7 @@ func NewSpentCoinState(hash util.Uint256, height uint32) *SpentCoinState { // DecodeBinary implements Serializable interface. func (s *SpentCoinState) DecodeBinary(br *io.BinReader) { - br.ReadLE(&s.txHash) + br.ReadBytes(s.txHash[:]) br.ReadLE(&s.txHeight) s.items = make(map[uint16]uint32) diff --git a/pkg/core/transaction/attribute.go b/pkg/core/transaction/attribute.go index 3cd92d333..61f208d79 100644 --- a/pkg/core/transaction/attribute.go +++ b/pkg/core/transaction/attribute.go @@ -22,7 +22,7 @@ func (attr *Attribute) DecodeBinary(br *io.BinReader) { if attr.Usage == ECDH02 || attr.Usage == ECDH03 { attr.Data = make([]byte, 33) attr.Data[0] = byte(attr.Usage) - br.ReadLE(attr.Data[1:]) + br.ReadBytes(attr.Data[1:]) return } var datasize uint64 @@ -47,7 +47,7 @@ func (attr *Attribute) DecodeBinary(br *io.BinReader) { return } attr.Data = make([]byte, datasize) - br.ReadLE(attr.Data) + br.ReadBytes(attr.Data) } // EncodeBinary implements Serializable interface. diff --git a/pkg/core/transaction/input.go b/pkg/core/transaction/input.go index 27d895afc..e303e10e5 100644 --- a/pkg/core/transaction/input.go +++ b/pkg/core/transaction/input.go @@ -16,7 +16,7 @@ type Input struct { // DecodeBinary implements Serializable interface. func (in *Input) DecodeBinary(br *io.BinReader) { - br.ReadLE(&in.PrevHash) + br.ReadBytes(in.PrevHash[:]) br.ReadLE(&in.PrevIndex) } diff --git a/pkg/core/transaction/output.go b/pkg/core/transaction/output.go index 1e31fa92a..34c836915 100644 --- a/pkg/core/transaction/output.go +++ b/pkg/core/transaction/output.go @@ -35,9 +35,9 @@ func NewOutput(assetID util.Uint256, amount util.Fixed8, scriptHash util.Uint160 // DecodeBinary implements Serializable interface. func (out *Output) DecodeBinary(br *io.BinReader) { - br.ReadLE(&out.AssetID) + br.ReadBytes(out.AssetID[:]) br.ReadLE(&out.Amount) - br.ReadLE(&out.ScriptHash) + br.ReadBytes(out.ScriptHash[:]) } // EncodeBinary implements Serializable interface. diff --git a/pkg/core/transaction/register.go b/pkg/core/transaction/register.go index cccb6f769..bba131263 100644 --- a/pkg/core/transaction/register.go +++ b/pkg/core/transaction/register.go @@ -40,7 +40,7 @@ func (tx *RegisterTX) DecodeBinary(br *io.BinReader) { tx.Owner = &keys.PublicKey{} tx.Owner.DecodeBinary(br) - br.ReadLE(&tx.Admin) + br.ReadBytes(tx.Admin[:]) } // EncodeBinary implements Serializable interface. diff --git a/pkg/crypto/keys/publickey.go b/pkg/crypto/keys/publickey.go index 8f5f3fde9..46a58370d 100644 --- a/pkg/crypto/keys/publickey.go +++ b/pkg/crypto/keys/publickey.go @@ -181,7 +181,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) { case 0x02, 0x03: // Compressed public keys xbytes := make([]byte, 32) - r.ReadLE(xbytes) + r.ReadBytes(xbytes) if r.Err != nil { return } @@ -194,8 +194,8 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) { case 0x04: xbytes := make([]byte, 32) ybytes := make([]byte, 32) - r.ReadLE(xbytes) - r.ReadLE(ybytes) + r.ReadBytes(xbytes) + r.ReadBytes(ybytes) if r.Err != nil { return } diff --git a/pkg/io/binaryReader.go b/pkg/io/binaryReader.go index 6bc67fd66..e7c07dcf8 100644 --- a/pkg/io/binaryReader.go +++ b/pkg/io/binaryReader.go @@ -132,10 +132,19 @@ func (r *BinReader) ReadVarUint() uint64 { func (r *BinReader) ReadVarBytes() []byte { n := r.ReadVarUint() b := make([]byte, n) - r.ReadLE(b) + r.ReadBytes(b) return b } +// ReadBytes copies fixed-size buffer from the reader to provided slice. +func (r *BinReader) ReadBytes(buf []byte) { + if r.Err != nil { + return + } + + _, r.Err = io.ReadFull(r.r, buf) +} + // ReadString calls ReadVarBytes and casts the results as a string. func (r *BinReader) ReadString() string { b := r.ReadVarBytes() diff --git a/pkg/io/binaryrw_test.go b/pkg/io/binaryrw_test.go index 7047357a8..40a6d42f2 100644 --- a/pkg/io/binaryrw_test.go +++ b/pkg/io/binaryrw_test.go @@ -332,3 +332,28 @@ func TestBinReader_ReadArray(t *testing.T) { r.Err = errors.New("error") require.Panics(t, func() { r.ReadArray(1) }) } + +func TestBinReader_ReadBytes(t *testing.T) { + data := []byte{0, 1, 2, 3, 4, 5, 6, 7} + r := NewBinReaderFromBuf(data) + + buf := make([]byte, 4) + r.ReadBytes(buf) + require.NoError(t, r.Err) + require.Equal(t, data[:4], buf) + + r.ReadBytes([]byte{}) + require.NoError(t, r.Err) + + buf = make([]byte, 3) + r.ReadBytes(buf) + require.NoError(t, r.Err) + require.Equal(t, data[4:7], buf) + + buf = make([]byte, 2) + r.ReadBytes(buf) + require.Error(t, r.Err) + + r.ReadBytes([]byte{}) + require.Error(t, r.Err) +} diff --git a/pkg/network/message.go b/pkg/network/message.go index 9459079ff..0b656194d 100644 --- a/pkg/network/message.go +++ b/pkg/network/message.go @@ -150,7 +150,7 @@ func (m *Message) CommandType() CommandType { // Decode decodes a Message from the given reader. func (m *Message) Decode(br *io.BinReader) error { br.ReadLE(&m.Magic) - br.ReadLE(&m.Command) + br.ReadBytes(m.Command[:]) br.ReadLE(&m.Length) br.ReadLE(&m.Checksum) if br.Err != nil { diff --git a/pkg/network/payload/address.go b/pkg/network/payload/address.go index c8a4f9ece..9c8d3444b 100644 --- a/pkg/network/payload/address.go +++ b/pkg/network/payload/address.go @@ -31,7 +31,7 @@ func NewAddressAndTime(e *net.TCPAddr, t time.Time) *AddressAndTime { func (p *AddressAndTime) DecodeBinary(br *io.BinReader) { br.ReadLE(&p.Timestamp) br.ReadLE(&p.Services) - br.ReadBE(&p.IP) + br.ReadBytes(p.IP[:]) br.ReadBE(&p.Port) } diff --git a/pkg/network/payload/getblocks.go b/pkg/network/payload/getblocks.go index 5c5caaebc..45e567119 100644 --- a/pkg/network/payload/getblocks.go +++ b/pkg/network/payload/getblocks.go @@ -24,7 +24,7 @@ func NewGetBlocks(start []util.Uint256, stop util.Uint256) *GetBlocks { // DecodeBinary implements Serializable interface. func (p *GetBlocks) DecodeBinary(br *io.BinReader) { br.ReadArray(&p.HashStart) - br.ReadLE(&p.HashStop) + br.ReadBytes(p.HashStop[:]) } // EncodeBinary implements Serializable interface. diff --git a/pkg/util/uint256.go b/pkg/util/uint256.go index 2c7085e69..81521e1b8 100644 --- a/pkg/util/uint256.go +++ b/pkg/util/uint256.go @@ -123,5 +123,5 @@ func (u Uint256) EncodeBinary(w *io.BinWriter) { // DecodeBinary implements io.Serializable interface. func (u *Uint256) DecodeBinary(r *io.BinReader) { - r.ReadBE(u[:]) + r.ReadBytes(u[:]) }