io: redo Serializable to return errors in BinReader/BinWriter

Further simplifies error handling.
This commit is contained in:
Roman Khimov 2019-09-16 19:31:49 +03:00
parent 0bb8950f89
commit d1a4e43c48
59 changed files with 418 additions and 605 deletions

View file

@ -20,8 +20,10 @@ func (a Accounts) getAndUpdate(s storage.Store, hash util.Uint160) (*AccountStat
account := &AccountState{} account := &AccountState{}
key := storage.AppendPrefix(storage.STAccount, hash.Bytes()) key := storage.AppendPrefix(storage.STAccount, hash.Bytes())
if b, err := s.Get(key); err == nil { if b, err := s.Get(key); err == nil {
if err := account.DecodeBinary(io.NewBinReaderFromBuf(b)); err != nil { r := io.NewBinReaderFromBuf(b)
return nil, fmt.Errorf("failed to decode (AccountState): %s", err) account.DecodeBinary(r)
if r.Err != nil {
return nil, fmt.Errorf("failed to decode (AccountState): %s", r.Err)
} }
} else { } else {
account = NewAccountState(hash) account = NewAccountState(hash)
@ -35,8 +37,9 @@ func (a Accounts) getAndUpdate(s storage.Store, hash util.Uint160) (*AccountStat
func (a Accounts) commit(b storage.Batch) error { func (a Accounts) commit(b storage.Batch) error {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
for hash, state := range a { for hash, state := range a {
if err := state.EncodeBinary(buf.BinWriter); err != nil { state.EncodeBinary(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
key := storage.AppendPrefix(storage.STAccount, hash.Bytes()) key := storage.AppendPrefix(storage.STAccount, hash.Bytes())
b.Put(key, buf.Bytes()) b.Put(key, buf.Bytes())
@ -66,7 +69,7 @@ func NewAccountState(scriptHash util.Uint160) *AccountState {
} }
// DecodeBinary decodes AccountState from the given BinReader. // DecodeBinary decodes AccountState from the given BinReader.
func (s *AccountState) DecodeBinary(br *io.BinReader) error { func (s *AccountState) DecodeBinary(br *io.BinReader) {
br.ReadLE(&s.Version) br.ReadLE(&s.Version)
br.ReadLE(&s.ScriptHash) br.ReadLE(&s.ScriptHash)
br.ReadLE(&s.IsFrozen) br.ReadLE(&s.IsFrozen)
@ -74,9 +77,7 @@ func (s *AccountState) DecodeBinary(br *io.BinReader) error {
s.Votes = make([]*keys.PublicKey, lenVotes) s.Votes = make([]*keys.PublicKey, lenVotes)
for i := 0; i < int(lenVotes); i++ { for i := 0; i < int(lenVotes); i++ {
s.Votes[i] = &keys.PublicKey{} s.Votes[i] = &keys.PublicKey{}
if err := s.Votes[i].DecodeBinary(br); err != nil { s.Votes[i].DecodeBinary(br)
return err
}
} }
s.Balances = make(map[util.Uint256]util.Fixed8) s.Balances = make(map[util.Uint256]util.Fixed8)
@ -88,20 +89,16 @@ func (s *AccountState) DecodeBinary(br *io.BinReader) error {
br.ReadLE(&val) br.ReadLE(&val)
s.Balances[key] = val s.Balances[key] = val
} }
return br.Err
} }
// EncodeBinary encodes AccountState to the given BinWriter. // EncodeBinary encodes AccountState to the given BinWriter.
func (s *AccountState) EncodeBinary(bw *io.BinWriter) error { func (s *AccountState) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(s.Version) bw.WriteLE(s.Version)
bw.WriteLE(s.ScriptHash) bw.WriteLE(s.ScriptHash)
bw.WriteLE(s.IsFrozen) bw.WriteLE(s.IsFrozen)
bw.WriteVarUint(uint64(len(s.Votes))) bw.WriteVarUint(uint64(len(s.Votes)))
for _, point := range s.Votes { for _, point := range s.Votes {
if err := point.EncodeBinary(bw); err != nil { point.EncodeBinary(bw)
return err
}
} }
balances := s.nonZeroBalances() balances := s.nonZeroBalances()
@ -110,8 +107,6 @@ func (s *AccountState) EncodeBinary(bw *io.BinWriter) error {
bw.WriteLE(k) bw.WriteLE(k)
bw.WriteLE(v) bw.WriteLE(v)
} }
return bw.Err
} }
// Returns only the non-zero balances for the account. // Returns only the non-zero balances for the account.

View file

@ -31,14 +31,13 @@ func TestDecodeEncodeAccountState(t *testing.T) {
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
if err := a.EncodeBinary(buf.BinWriter); err != nil { a.EncodeBinary(buf.BinWriter)
t.Fatal(err) assert.Nil(t, buf.Err)
}
aDecode := &AccountState{} aDecode := &AccountState{}
if err := aDecode.DecodeBinary(io.NewBinReaderFromBuf(buf.Bytes())); err != nil { r := io.NewBinReaderFromBuf(buf.Bytes())
t.Fatal(err) aDecode.DecodeBinary(r)
} assert.Nil(t, r.Err)
assert.Equal(t, a.Version, aDecode.Version) assert.Equal(t, a.Version, aDecode.Version)
assert.Equal(t, a.ScriptHash, aDecode.ScriptHash) assert.Equal(t, a.ScriptHash, aDecode.ScriptHash)

View file

@ -16,8 +16,9 @@ type Assets map[util.Uint256]*AssetState
func (a Assets) commit(b storage.Batch) error { func (a Assets) commit(b storage.Batch) error {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
for hash, state := range a { for hash, state := range a {
if err := state.EncodeBinary(buf.BinWriter); err != nil { state.EncodeBinary(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
key := storage.AppendPrefix(storage.STAsset, hash.Bytes()) key := storage.AppendPrefix(storage.STAsset, hash.Bytes())
b.Put(key, buf.Bytes()) b.Put(key, buf.Bytes())
@ -43,8 +44,8 @@ type AssetState struct {
IsFrozen bool IsFrozen bool
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (a *AssetState) DecodeBinary(br *io.BinReader) error { func (a *AssetState) DecodeBinary(br *io.BinReader) {
br.ReadLE(&a.ID) br.ReadLE(&a.ID)
br.ReadLE(&a.AssetType) br.ReadLE(&a.AssetType)
@ -56,23 +57,16 @@ func (a *AssetState) DecodeBinary(br *io.BinReader) error {
br.ReadLE(&a.FeeMode) br.ReadLE(&a.FeeMode)
br.ReadLE(&a.FeeAddress) br.ReadLE(&a.FeeAddress)
if br.Err != nil {
return br.Err
}
a.Owner = &keys.PublicKey{} a.Owner = &keys.PublicKey{}
if err := a.Owner.DecodeBinary(br); err != nil { a.Owner.DecodeBinary(br)
return err
}
br.ReadLE(&a.Admin) br.ReadLE(&a.Admin)
br.ReadLE(&a.Issuer) br.ReadLE(&a.Issuer)
br.ReadLE(&a.Expiration) br.ReadLE(&a.Expiration)
br.ReadLE(&a.IsFrozen) br.ReadLE(&a.IsFrozen)
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (a *AssetState) EncodeBinary(bw *io.BinWriter) error { func (a *AssetState) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(a.ID) bw.WriteLE(a.ID)
bw.WriteLE(a.AssetType) bw.WriteLE(a.AssetType)
bw.WriteString(a.Name) bw.WriteString(a.Name)
@ -82,17 +76,12 @@ func (a *AssetState) EncodeBinary(bw *io.BinWriter) error {
bw.WriteLE(a.FeeMode) bw.WriteLE(a.FeeMode)
bw.WriteLE(a.FeeAddress) bw.WriteLE(a.FeeAddress)
if bw.Err != nil { a.Owner.EncodeBinary(bw)
return bw.Err
}
if err := a.Owner.EncodeBinary(bw); err != nil {
return err
}
bw.WriteLE(a.Admin) bw.WriteLE(a.Admin)
bw.WriteLE(a.Issuer) bw.WriteLE(a.Issuer)
bw.WriteLE(a.Expiration) bw.WriteLE(a.Expiration)
bw.WriteLE(a.IsFrozen) bw.WriteLE(a.IsFrozen)
return bw.Err
} }
// GetName returns the asset name based on its type. // GetName returns the asset name based on its type.

View file

@ -27,8 +27,11 @@ func TestEncodeDecodeAssetState(t *testing.T) {
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
assert.Nil(t, asset.EncodeBinary(buf.BinWriter)) asset.EncodeBinary(buf.BinWriter)
assert.Nil(t, buf.Err)
assetDecode := &AssetState{} assetDecode := &AssetState{}
assert.Nil(t, assetDecode.DecodeBinary(io.NewBinReaderFromBuf(buf.Bytes()))) r := io.NewBinReaderFromBuf(buf.Bytes())
assetDecode.DecodeBinary(r)
assert.Nil(t, r.Err)
assert.Equal(t, asset, assetDecode) assert.Equal(t, asset, assetDecode)
} }

View file

@ -72,20 +72,13 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
} }
br := io.NewBinReaderFromBuf(b) br := io.NewBinReaderFromBuf(b)
if err := block.decodeHashableFields(br); err != nil { block.decodeHashableFields(br)
return block, err
}
var padding uint8 var padding uint8
br.ReadLE(&padding) br.ReadLE(&padding)
if br.Err != nil {
return block, br.Err
}
block.Script = &transaction.Witness{} block.Script = &transaction.Witness{}
if err := block.Script.DecodeBinary(br); err != nil { block.Script.DecodeBinary(br)
return block, err
}
lenTX := br.ReadVarUint() lenTX := br.ReadVarUint()
block.Transactions = make([]*transaction.Transaction, lenTX) block.Transactions = make([]*transaction.Transaction, lenTX)
@ -103,16 +96,9 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
// Notice that only the hashes of the transactions are stored. // Notice that only the hashes of the transactions are stored.
func (b *Block) Trim() ([]byte, error) { func (b *Block) Trim() ([]byte, error) {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
if err := b.encodeHashableFields(buf.BinWriter); err != nil { b.encodeHashableFields(buf.BinWriter)
return nil, err
}
buf.WriteLE(uint8(1)) buf.WriteLE(uint8(1))
if buf.Err != nil { b.Script.EncodeBinary(buf.BinWriter)
return nil, buf.Err
}
if err := b.Script.EncodeBinary(buf.BinWriter); err != nil {
return nil, err
}
buf.WriteVarUint(uint64(len(b.Transactions))) buf.WriteVarUint(uint64(len(b.Transactions)))
for _, tx := range b.Transactions { for _, tx := range b.Transactions {
@ -124,42 +110,25 @@ func (b *Block) Trim() ([]byte, error) {
return buf.Bytes(), nil return buf.Bytes(), nil
} }
// DecodeBinary decodes the block from the given reader. // DecodeBinary decodes the block from the given BinReader, implementing
func (b *Block) DecodeBinary(br *io.BinReader) error { // Serializable interface.
if err := b.BlockBase.DecodeBinary(br); err != nil { func (b *Block) DecodeBinary(br *io.BinReader) {
return err b.BlockBase.DecodeBinary(br)
}
lentx := br.ReadVarUint() lentx := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
b.Transactions = make([]*transaction.Transaction, lentx) b.Transactions = make([]*transaction.Transaction, lentx)
for i := 0; i < int(lentx); i++ { for i := 0; i < int(lentx); i++ {
b.Transactions[i] = &transaction.Transaction{} b.Transactions[i] = &transaction.Transaction{}
if err := b.Transactions[i].DecodeBinary(br); err != nil { b.Transactions[i].DecodeBinary(br)
return err
}
} }
return nil
} }
// EncodeBinary encodes the block to the given writer. // EncodeBinary encodes the block to the given BinWriter, implementing
func (b *Block) EncodeBinary(bw *io.BinWriter) error { // Serializable interface.
err := b.BlockBase.EncodeBinary(bw) func (b *Block) EncodeBinary(bw *io.BinWriter) {
if err != nil { b.BlockBase.EncodeBinary(bw)
return err
}
bw.WriteVarUint(uint64(len(b.Transactions))) bw.WriteVarUint(uint64(len(b.Transactions)))
if bw.Err != nil {
return err
}
for _, tx := range b.Transactions { for _, tx := range b.Transactions {
err := tx.EncodeBinary(bw) tx.EncodeBinary(bw)
if err != nil {
return err
}
} }
return nil
} }

View file

@ -58,35 +58,26 @@ func (b *BlockBase) Hash() util.Uint256 {
return b.hash return b.hash
} }
// DecodeBinary implements the payload interface. // DecodeBinary implements Serializable interface.
func (b *BlockBase) DecodeBinary(br *io.BinReader) error { func (b *BlockBase) DecodeBinary(br *io.BinReader) {
if err := b.decodeHashableFields(br); err != nil { b.decodeHashableFields(br)
return err
}
var padding uint8 var padding uint8
br.ReadLE(&padding) br.ReadLE(&padding)
if br.Err != nil {
return br.Err
}
if padding != 1 { if padding != 1 {
return fmt.Errorf("format error: padding must equal 1 got %d", padding) br.Err = fmt.Errorf("format error: padding must equal 1 got %d", padding)
return
} }
b.Script = &transaction.Witness{} b.Script = &transaction.Witness{}
return b.Script.DecodeBinary(br) b.Script.DecodeBinary(br)
} }
// EncodeBinary implements the Payload interface // EncodeBinary implements Serializable interface
func (b *BlockBase) EncodeBinary(bw *io.BinWriter) error { func (b *BlockBase) EncodeBinary(bw *io.BinWriter) {
if err := b.encodeHashableFields(bw); err != nil { b.encodeHashableFields(bw)
return err
}
bw.WriteLE(uint8(1)) bw.WriteLE(uint8(1))
if bw.Err != nil { b.Script.EncodeBinary(bw)
return bw.Err
}
return b.Script.EncodeBinary(bw)
} }
// createHash creates the hash of the block. // createHash creates the hash of the block.
@ -97,8 +88,9 @@ func (b *BlockBase) EncodeBinary(bw *io.BinWriter) error {
// the modification of transaction will influence the hash value of the block. // the modification of transaction will influence the hash value of the block.
func (b *BlockBase) createHash() error { func (b *BlockBase) createHash() error {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
if err := b.encodeHashableFields(buf.BinWriter); err != nil { b.encodeHashableFields(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
b.hash = hash.DoubleSha256(buf.Bytes()) b.hash = hash.DoubleSha256(buf.Bytes())
@ -107,7 +99,7 @@ func (b *BlockBase) createHash() error {
// encodeHashableFields will only encode the fields used for hashing. // encodeHashableFields will only encode the fields used for hashing.
// see Hash() for more information about the fields. // see Hash() for more information about the fields.
func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) error { func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) {
bw.WriteLE(b.Version) bw.WriteLE(b.Version)
bw.WriteLE(b.PrevHash) bw.WriteLE(b.PrevHash)
bw.WriteLE(b.MerkleRoot) bw.WriteLE(b.MerkleRoot)
@ -115,12 +107,11 @@ func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) error {
bw.WriteLE(b.Index) bw.WriteLE(b.Index)
bw.WriteLE(b.ConsensusData) bw.WriteLE(b.ConsensusData)
bw.WriteLE(b.NextConsensus) bw.WriteLE(b.NextConsensus)
return bw.Err
} }
// decodeHashableFields will only decode the fields used for hashing. // decodeHashableFields will only decode the fields used for hashing.
// see Hash() for more information about the fields. // see Hash() for more information about the fields.
func (b *BlockBase) decodeHashableFields(br *io.BinReader) error { func (b *BlockBase) decodeHashableFields(br *io.BinReader) {
br.ReadLE(&b.Version) br.ReadLE(&b.Version)
br.ReadLE(&b.PrevHash) br.ReadLE(&b.PrevHash)
br.ReadLE(&b.MerkleRoot) br.ReadLE(&b.MerkleRoot)
@ -129,11 +120,9 @@ func (b *BlockBase) decodeHashableFields(br *io.BinReader) error {
br.ReadLE(&b.ConsensusData) br.ReadLE(&b.ConsensusData)
br.ReadLE(&b.NextConsensus) br.ReadLE(&b.NextConsensus)
if br.Err != nil {
return br.Err
}
// Make the hash of the block here so we dont need to do this // Make the hash of the block here so we dont need to do this
// again. // again.
return b.createHash() if br.Err == nil {
br.Err = b.createHash()
}
} }

View file

@ -24,9 +24,9 @@ func TestDecodeBlock1(t *testing.T) {
} }
block := &Block{} block := &Block{}
if err := block.DecodeBinary(io.NewBinReaderFromBuf(b)); err != nil { r := io.NewBinReaderFromBuf(b)
t.Fatal(err) block.DecodeBinary(r)
} assert.Nil(t, r.Err)
assert.Equal(t, uint32(data["index"].(float64)), block.Index) assert.Equal(t, uint32(data["index"].(float64)), block.Index)
assert.Equal(t, uint32(data["version"].(float64)), block.Version) assert.Equal(t, uint32(data["version"].(float64)), block.Version)
@ -110,8 +110,8 @@ func TestBinBlockDecodeEncode(t *testing.T) {
b := Block{} b := Block{}
r := io.NewBinReaderFromBuf(rawtxBytes) r := io.NewBinReaderFromBuf(rawtxBytes)
err := b.DecodeBinary(r) b.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
expected := map[string]bool{ // 18 trans expected := map[string]bool{ // 18 trans
"009f61f481f47eb7478e887871e4e744669d461b13d68e04250035260171d706": false, "009f61f481f47eb7478e887871e4e744669d461b13d68e04250035260171d706": false,
@ -167,8 +167,8 @@ func TestBinBlockDecodeEncode(t *testing.T) {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err = b.EncodeBinary(buf.BinWriter) b.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes()))
} }
@ -186,8 +186,8 @@ func TestBlockSizeCalculation(t *testing.T) {
b := Block{} b := Block{}
r := io.NewBinReaderFromBuf(rawBlockBytes) r := io.NewBinReaderFromBuf(rawBlockBytes)
err := b.DecodeBinary(r) b.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
expected := []struct { expected := []struct {
ID string ID string
@ -252,8 +252,8 @@ func TestBlockSizeCalculation(t *testing.T) {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err = b.EncodeBinary(buf.BinWriter) b.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, r.Err)
benc := buf.Bytes() benc := buf.Bytes()
// test size of the block // test size of the block
assert.Equal(t, 7360, len(benc)) assert.Equal(t, 7360, len(benc))

View file

@ -254,8 +254,9 @@ func (bc *Blockchain) processHeader(h *Header, batch storage.Batch, headerList *
} }
buf.Reset() buf.Reset()
if err := h.EncodeBinary(buf.BinWriter); err != nil { h.EncodeBinary(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
key := storage.AppendPrefix(storage.DataBlock, h.Hash().BytesReverse()) key := storage.AppendPrefix(storage.DataBlock, h.Hash().BytesReverse())
@ -470,14 +471,13 @@ func (bc *Blockchain) GetTransaction(hash util.Uint256) (*transaction.Transactio
var height uint32 var height uint32
r.ReadLE(&height) r.ReadLE(&height)
tx := &transaction.Transaction{}
tx.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
return nil, 0, r.Err return nil, 0, r.Err
} }
tx := &transaction.Transaction{}
if err := tx.DecodeBinary(r); err != nil {
return nil, 0, err
}
return tx, height, nil return tx, height, nil
} }
@ -578,7 +578,9 @@ func (bc *Blockchain) GetAssetState(assetID util.Uint256) *AssetState {
var as *AssetState var as *AssetState
bc.Store.Seek(storage.STAsset.Bytes(), func(k, v []byte) { bc.Store.Seek(storage.STAsset.Bytes(), func(k, v []byte) {
var a AssetState var a AssetState
if err := a.DecodeBinary(io.NewBinReaderFromBuf(v)); err == nil && a.ID == assetID { r := io.NewBinReaderFromBuf(v)
a.DecodeBinary(r)
if r.Err == nil && a.ID == assetID {
as = &a as = &a
} }
}) })
@ -591,7 +593,9 @@ func (bc *Blockchain) GetAccountState(scriptHash util.Uint160) *AccountState {
var as *AccountState var as *AccountState
bc.Store.Seek(storage.STAccount.Bytes(), func(k, v []byte) { bc.Store.Seek(storage.STAccount.Bytes(), func(k, v []byte) {
var a AccountState var a AccountState
if err := a.DecodeBinary(io.NewBinReaderFromBuf(v)); err == nil && a.ScriptHash == scriptHash { r := io.NewBinReaderFromBuf(v)
a.DecodeBinary(r)
if r.Err == nil && a.ScriptHash == scriptHash {
as = &a as = &a
} }
}) })

View file

@ -14,28 +14,20 @@ type Header struct {
_ uint8 _ uint8
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (h *Header) DecodeBinary(r *io.BinReader) error { func (h *Header) DecodeBinary(r *io.BinReader) {
if err := h.BlockBase.DecodeBinary(r); err != nil { h.BlockBase.DecodeBinary(r)
return err
}
var padding uint8 var padding uint8
r.ReadLE(&padding) r.ReadLE(&padding)
if r.Err != nil {
return r.Err
}
if padding != 0 { if padding != 0 {
return fmt.Errorf("format error: padding must equal 0 got %d", padding) r.Err = fmt.Errorf("format error: padding must equal 0 got %d", padding)
} }
return nil
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (h *Header) EncodeBinary(w *io.BinWriter) error { func (h *Header) EncodeBinary(w *io.BinWriter) {
h.BlockBase.EncodeBinary(w) h.BlockBase.EncodeBinary(w)
w.WriteLE(uint8(0)) w.WriteLE(uint8(0))
return w.Err
} }

View file

@ -27,14 +27,13 @@ func TestHeaderEncodeDecode(t *testing.T) {
}} }}
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
if err := header.EncodeBinary(buf.BinWriter); err != nil { header.EncodeBinary(buf.BinWriter)
t.Fatal(err) assert.Nil(t, buf.Err)
}
headerDecode := &Header{} headerDecode := &Header{}
if err := headerDecode.DecodeBinary(io.NewBinReaderFromBuf(buf.Bytes())); err != nil { r := io.NewBinReaderFromBuf(buf.Bytes())
t.Fatal(err) headerDecode.DecodeBinary(r)
} assert.Nil(t, r.Err)
assert.Equal(t, header.Version, headerDecode.Version, "expected both versions to be equal") assert.Equal(t, header.Version, headerDecode.Version, "expected both versions to be equal")
assert.Equal(t, header.PrevHash, headerDecode.PrevHash, "expected both prev hashes to be equal") assert.Equal(t, header.PrevHash, headerDecode.PrevHash, "expected both prev hashes to be equal")
assert.Equal(t, header.MerkleRoot, headerDecode.MerkleRoot, "expected both merkle roots to be equal") assert.Equal(t, header.MerkleRoot, headerDecode.MerkleRoot, "expected both merkle roots to be equal")

View file

@ -63,8 +63,10 @@ func getDecodedBlock(t *testing.T, i int) *Block {
} }
block := &Block{} block := &Block{}
if err := block.DecodeBinary(io.NewBinReaderFromBuf(b)); err != nil { r := io.NewBinReaderFromBuf(b)
t.Fatal(err) block.DecodeBinary(r)
if r.Err != nil {
t.Fatal(r.Err)
} }
return block return block

View file

@ -20,8 +20,10 @@ func (s SpentCoins) getAndUpdate(store storage.Store, hash util.Uint256) (*Spent
spent := &SpentCoinState{} spent := &SpentCoinState{}
key := storage.AppendPrefix(storage.STSpentCoin, hash.BytesReverse()) key := storage.AppendPrefix(storage.STSpentCoin, hash.BytesReverse())
if b, err := store.Get(key); err == nil { if b, err := store.Get(key); err == nil {
if err := spent.DecodeBinary(io.NewBinReaderFromBuf(b)); err != nil { r := io.NewBinReaderFromBuf(b)
return nil, fmt.Errorf("failed to decode (UnspentCoinState): %s", err) spent.DecodeBinary(r)
if r.Err != nil {
return nil, fmt.Errorf("failed to decode (UnspentCoinState): %s", r.Err)
} }
} else { } else {
spent = &SpentCoinState{ spent = &SpentCoinState{
@ -36,8 +38,9 @@ func (s SpentCoins) getAndUpdate(store storage.Store, hash util.Uint256) (*Spent
func (s SpentCoins) commit(b storage.Batch) error { func (s SpentCoins) commit(b storage.Batch) error {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
for hash, state := range s { for hash, state := range s {
if err := state.EncodeBinary(buf.BinWriter); err != nil { state.EncodeBinary(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
key := storage.AppendPrefix(storage.STSpentCoin, hash.BytesReverse()) key := storage.AppendPrefix(storage.STSpentCoin, hash.BytesReverse())
b.Put(key, buf.Bytes()) b.Put(key, buf.Bytes())
@ -64,8 +67,8 @@ func NewSpentCoinState(hash util.Uint256, height uint32) *SpentCoinState {
} }
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (s *SpentCoinState) DecodeBinary(br *io.BinReader) error { func (s *SpentCoinState) DecodeBinary(br *io.BinReader) {
br.ReadLE(&s.txHash) br.ReadLE(&s.txHash)
br.ReadLE(&s.txHeight) br.ReadLE(&s.txHeight)
@ -80,11 +83,10 @@ func (s *SpentCoinState) DecodeBinary(br *io.BinReader) error {
br.ReadLE(&value) br.ReadLE(&value)
s.items[key] = value s.items[key] = value
} }
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (s *SpentCoinState) EncodeBinary(bw *io.BinWriter) error { func (s *SpentCoinState) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(s.txHash) bw.WriteLE(s.txHash)
bw.WriteLE(s.txHeight) bw.WriteLE(s.txHeight)
bw.WriteVarUint(uint64(len(s.items))) bw.WriteVarUint(uint64(len(s.items)))
@ -92,5 +94,4 @@ func (s *SpentCoinState) EncodeBinary(bw *io.BinWriter) error {
bw.WriteLE(k) bw.WriteLE(k)
bw.WriteLE(v) bw.WriteLE(v)
} }
return bw.Err
} }

View file

@ -21,9 +21,12 @@ func TestEncodeDecodeSpentCoinState(t *testing.T) {
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
assert.Nil(t, spent.EncodeBinary(buf.BinWriter)) spent.EncodeBinary(buf.BinWriter)
assert.Nil(t, buf.Err)
spentDecode := new(SpentCoinState) spentDecode := new(SpentCoinState)
assert.Nil(t, spentDecode.DecodeBinary(io.NewBinReaderFromBuf(buf.Bytes()))) r := io.NewBinReaderFromBuf(buf.Bytes())
spentDecode.DecodeBinary(r)
assert.Nil(t, r.Err)
assert.Equal(t, spent, spentDecode) assert.Equal(t, spent, spentDecode)
} }

View file

@ -14,8 +14,8 @@ type Attribute struct {
Data []byte Data []byte
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (attr *Attribute) DecodeBinary(br *io.BinReader) error { func (attr *Attribute) DecodeBinary(br *io.BinReader) {
br.ReadLE(&attr.Usage) br.ReadLE(&attr.Usage)
// very special case // very special case
@ -23,7 +23,7 @@ func (attr *Attribute) DecodeBinary(br *io.BinReader) error {
attr.Data = make([]byte, 33) attr.Data = make([]byte, 33)
attr.Data[0] = byte(attr.Usage) attr.Data[0] = byte(attr.Usage)
br.ReadLE(attr.Data[1:]) br.ReadLE(attr.Data[1:])
return br.Err return
} }
var datasize uint64 var datasize uint64
switch attr.Usage { switch attr.Usage {
@ -43,15 +43,15 @@ func (attr *Attribute) DecodeBinary(br *io.BinReader) error {
Remark12, Remark13, Remark14, Remark15: Remark12, Remark13, Remark14, Remark15:
datasize = br.ReadVarUint() datasize = br.ReadVarUint()
default: default:
return fmt.Errorf("failed decoding TX attribute usage: 0x%2x", int(attr.Usage)) br.Err = fmt.Errorf("failed decoding TX attribute usage: 0x%2x", int(attr.Usage))
return
} }
attr.Data = make([]byte, datasize) attr.Data = make([]byte, datasize)
br.ReadLE(attr.Data) br.ReadLE(attr.Data)
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (attr *Attribute) EncodeBinary(bw *io.BinWriter) error { func (attr *Attribute) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(&attr.Usage) bw.WriteLE(&attr.Usage)
switch attr.Usage { switch attr.Usage {
case ECDH02, ECDH03: case ECDH02, ECDH03:
@ -68,10 +68,8 @@ func (attr *Attribute) EncodeBinary(bw *io.BinWriter) error {
Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13, Hash14, Hash15: Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13, Hash14, Hash15:
bw.WriteLE(attr.Data) bw.WriteLE(attr.Data)
default: default:
return fmt.Errorf("failed encoding TX attribute usage: 0x%2x", attr.Usage) bw.Err = fmt.Errorf("failed encoding TX attribute usage: 0x%2x", attr.Usage)
} }
return bw.Err
} }
// MarshalJSON implements the json Marschaller interface // MarshalJSON implements the json Marschaller interface

View file

@ -9,32 +9,20 @@ type ClaimTX struct {
Claims []*Input Claims []*Input
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *ClaimTX) DecodeBinary(br *io.BinReader) error { func (tx *ClaimTX) DecodeBinary(br *io.BinReader) {
lenClaims := br.ReadVarUint() lenClaims := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
tx.Claims = make([]*Input, lenClaims) tx.Claims = make([]*Input, lenClaims)
for i := 0; i < int(lenClaims); i++ { for i := 0; i < int(lenClaims); i++ {
tx.Claims[i] = &Input{} tx.Claims[i] = &Input{}
if err := tx.Claims[i].DecodeBinary(br); err != nil { tx.Claims[i].DecodeBinary(br)
return err
}
} }
return nil
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *ClaimTX) EncodeBinary(bw *io.BinWriter) error { func (tx *ClaimTX) EncodeBinary(bw *io.BinWriter) {
bw.WriteVarUint(uint64(len(tx.Claims))) bw.WriteVarUint(uint64(len(tx.Claims)))
if bw.Err != nil {
return bw.Err
}
for _, claim := range tx.Claims { for _, claim := range tx.Claims {
if err := claim.EncodeBinary(bw); err != nil { claim.EncodeBinary(bw)
return err
}
} }
return nil
} }

View file

@ -15,12 +15,10 @@ func NewContractTX() *Transaction {
} }
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *ContractTX) DecodeBinary(r *io.BinReader) error { func (tx *ContractTX) DecodeBinary(r *io.BinReader) {
return nil
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *ContractTX) EncodeBinary(w *io.BinWriter) error { func (tx *ContractTX) EncodeBinary(w *io.BinWriter) {
return nil
} }

View file

@ -31,7 +31,7 @@ func TestEncodeDecodeContract(t *testing.T) {
// Encode // Encode
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := tx.EncodeBinary(buf.BinWriter) tx.EncodeBinary(buf.BinWriter)
assert.Equal(t, nil, err) assert.Equal(t, nil, buf.Err)
assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes()))
} }

View file

@ -15,13 +15,13 @@ type EnrollmentTX struct {
PublicKey *keys.PublicKey PublicKey *keys.PublicKey
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *EnrollmentTX) DecodeBinary(r *io.BinReader) error { func (tx *EnrollmentTX) DecodeBinary(r *io.BinReader) {
tx.PublicKey = &keys.PublicKey{} tx.PublicKey = &keys.PublicKey{}
return tx.PublicKey.DecodeBinary(r) tx.PublicKey.DecodeBinary(r)
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *EnrollmentTX) EncodeBinary(w *io.BinWriter) error { func (tx *EnrollmentTX) EncodeBinary(w *io.BinWriter) {
return tx.PublicKey.EncodeBinary(w) tx.PublicKey.EncodeBinary(w)
} }

View file

@ -17,8 +17,8 @@ func TestEncodeDecodeEnrollment(t *testing.T) {
assert.Equal(t, 0, int(tx.Version)) assert.Equal(t, 0, int(tx.Version))
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := tx.EncodeBinary(buf.BinWriter) tx.EncodeBinary(buf.BinWriter)
assert.Equal(t, nil, err) assert.Equal(t, nil, buf.Err)
assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes()))
} }

View file

@ -21,7 +21,8 @@ func decodeTransaction(rawTX string, t *testing.T) *Transaction {
b, err1 := hex.DecodeString(rawTX) b, err1 := hex.DecodeString(rawTX)
assert.Nil(t, err1) assert.Nil(t, err1)
tx := &Transaction{} tx := &Transaction{}
err2 := tx.DecodeBinary(io.NewBinReaderFromBuf(b)) r := io.NewBinReaderFromBuf(b)
assert.Nil(t, err2) tx.DecodeBinary(r)
assert.Nil(t, r.Err)
return tx return tx
} }

View file

@ -14,16 +14,14 @@ type Input struct {
PrevIndex uint16 `json:"vout"` PrevIndex uint16 `json:"vout"`
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (in *Input) DecodeBinary(br *io.BinReader) error { func (in *Input) DecodeBinary(br *io.BinReader) {
br.ReadLE(&in.PrevHash) br.ReadLE(&in.PrevHash)
br.ReadLE(&in.PrevIndex) br.ReadLE(&in.PrevIndex)
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (in *Input) EncodeBinary(bw *io.BinWriter) error { func (in *Input) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(in.PrevHash) bw.WriteLE(in.PrevHash)
bw.WriteLE(in.PrevIndex) bw.WriteLE(in.PrevIndex)
return bw.Err
} }

View file

@ -31,22 +31,20 @@ func NewInvocationTX(script []byte) *Transaction {
} }
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *InvocationTX) DecodeBinary(br *io.BinReader) error { func (tx *InvocationTX) DecodeBinary(br *io.BinReader) {
tx.Script = br.ReadBytes() tx.Script = br.ReadBytes()
if tx.Version >= 1 { if tx.Version >= 1 {
br.ReadLE(&tx.Gas) br.ReadLE(&tx.Gas)
} else { } else {
tx.Gas = util.Fixed8FromInt64(0) tx.Gas = util.Fixed8FromInt64(0)
} }
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *InvocationTX) EncodeBinary(bw *io.BinWriter) error { func (tx *InvocationTX) EncodeBinary(bw *io.BinWriter) {
bw.WriteBytes(tx.Script) bw.WriteBytes(tx.Script)
if tx.Version >= 1 { if tx.Version >= 1 {
bw.WriteLE(tx.Gas) bw.WriteLE(tx.Gas)
} }
return bw.Err
} }

View file

@ -8,12 +8,10 @@ import (
// This TX has not special attributes. // This TX has not special attributes.
type IssueTX struct{} type IssueTX struct{}
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *IssueTX) DecodeBinary(r *io.BinReader) error { func (tx *IssueTX) DecodeBinary(r *io.BinReader) {
return nil
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *IssueTX) EncodeBinary(w *io.BinWriter) error { func (tx *IssueTX) EncodeBinary(w *io.BinWriter) {
return nil
} }

View file

@ -10,14 +10,12 @@ type MinerTX struct {
Nonce uint32 Nonce uint32
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *MinerTX) DecodeBinary(r *io.BinReader) error { func (tx *MinerTX) DecodeBinary(r *io.BinReader) {
r.ReadLE(&tx.Nonce) r.ReadLE(&tx.Nonce)
return r.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *MinerTX) EncodeBinary(w *io.BinWriter) error { func (tx *MinerTX) EncodeBinary(w *io.BinWriter) {
w.WriteLE(tx.Nonce) w.WriteLE(tx.Nonce)
return w.Err
} }

View file

@ -23,8 +23,8 @@ func TestEncodeDecodeMiner(t *testing.T) {
// Encode // Encode
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := tx.EncodeBinary(buf.BinWriter) tx.EncodeBinary(buf.BinWriter)
assert.Equal(t, nil, err) assert.Equal(t, nil, buf.Err)
assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes()))
} }

View file

@ -33,20 +33,18 @@ func NewOutput(assetID util.Uint256, amount util.Fixed8, scriptHash util.Uint160
} }
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (out *Output) DecodeBinary(br *io.BinReader) error { func (out *Output) DecodeBinary(br *io.BinReader) {
br.ReadLE(&out.AssetID) br.ReadLE(&out.AssetID)
br.ReadLE(&out.Amount) br.ReadLE(&out.Amount)
br.ReadLE(&out.ScriptHash) br.ReadLE(&out.ScriptHash)
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (out *Output) EncodeBinary(bw *io.BinWriter) error { func (out *Output) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(out.AssetID) bw.WriteLE(out.AssetID)
bw.WriteLE(out.Amount) bw.WriteLE(out.Amount)
bw.WriteLE(out.ScriptHash) bw.WriteLE(out.ScriptHash)
return bw.Err
} }
// MarshalJSON implements the Marshaler interface // MarshalJSON implements the Marshaler interface

View file

@ -20,8 +20,8 @@ type PublishTX struct {
Version uint8 // Version of the parent struct Transaction. Used in reading NeedStorage flag. Version uint8 // Version of the parent struct Transaction. Used in reading NeedStorage flag.
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *PublishTX) DecodeBinary(br *io.BinReader) error { func (tx *PublishTX) DecodeBinary(br *io.BinReader) {
tx.Script = br.ReadBytes() tx.Script = br.ReadBytes()
lenParams := br.ReadVarUint() lenParams := br.ReadVarUint()
@ -47,12 +47,10 @@ func (tx *PublishTX) DecodeBinary(br *io.BinReader) error {
tx.Author = br.ReadString() tx.Author = br.ReadString()
tx.Email = br.ReadString() tx.Email = br.ReadString()
tx.Description = br.ReadString() tx.Description = br.ReadString()
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *PublishTX) EncodeBinary(bw *io.BinWriter) error { func (tx *PublishTX) EncodeBinary(bw *io.BinWriter) {
bw.WriteBytes(tx.Script) bw.WriteBytes(tx.Script)
bw.WriteVarUint(uint64(len(tx.ParamList))) bw.WriteVarUint(uint64(len(tx.ParamList)))
for _, param := range tx.ParamList { for _, param := range tx.ParamList {
@ -67,5 +65,4 @@ func (tx *PublishTX) EncodeBinary(bw *io.BinWriter) error {
bw.WriteString(tx.Author) bw.WriteString(tx.Author)
bw.WriteString(tx.Email) bw.WriteString(tx.Email)
bw.WriteString(tx.Description) bw.WriteString(tx.Description)
return bw.Err
} }

View file

@ -28,34 +28,27 @@ type RegisterTX struct {
Admin util.Uint160 Admin util.Uint160
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *RegisterTX) DecodeBinary(br *io.BinReader) error { func (tx *RegisterTX) DecodeBinary(br *io.BinReader) {
br.ReadLE(&tx.AssetType) br.ReadLE(&tx.AssetType)
tx.Name = br.ReadString() tx.Name = br.ReadString()
br.ReadLE(&tx.Amount) br.ReadLE(&tx.Amount)
br.ReadLE(&tx.Precision) br.ReadLE(&tx.Precision)
if br.Err != nil {
return br.Err
}
tx.Owner = &keys.PublicKey{} tx.Owner = &keys.PublicKey{}
if err := tx.Owner.DecodeBinary(br); err != nil { tx.Owner.DecodeBinary(br)
return err
}
br.ReadLE(&tx.Admin) br.ReadLE(&tx.Admin)
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *RegisterTX) EncodeBinary(bw *io.BinWriter) error { func (tx *RegisterTX) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(tx.AssetType) bw.WriteLE(tx.AssetType)
bw.WriteString(tx.Name) bw.WriteString(tx.Name)
bw.WriteLE(tx.Amount) bw.WriteLE(tx.Amount)
bw.WriteLE(tx.Precision) bw.WriteLE(tx.Precision)
bw.WriteLE(tx.Owner.Bytes()) bw.WriteLE(tx.Owner.Bytes())
bw.WriteLE(tx.Admin) bw.WriteLE(tx.Admin)
return bw.Err
} }

View file

@ -27,11 +27,14 @@ func TestRegisterTX(t *testing.T) {
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
assert.Nil(t, tx.EncodeBinary(buf.BinWriter)) tx.EncodeBinary(buf.BinWriter)
assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
txDecode := &Transaction{} txDecode := &Transaction{}
assert.Nil(t, txDecode.DecodeBinary(io.NewBinReaderFromBuf(b))) r := io.NewBinReaderFromBuf(b)
txDecode.DecodeBinary(r)
assert.Nil(t, r.Err)
txData := tx.Data.(*RegisterTX) txData := tx.Data.(*RegisterTX)
txDecodeData := txDecode.Data.(*RegisterTX) txDecodeData := txDecode.Data.(*RegisterTX)
assert.Equal(t, txData, txDecodeData) assert.Equal(t, txData, txDecodeData)
@ -46,7 +49,9 @@ func TestDecodeRegisterTXFromRawString(t *testing.T) {
} }
tx := &Transaction{} tx := &Transaction{}
assert.Nil(t, tx.DecodeBinary(io.NewBinReaderFromBuf(b))) r := io.NewBinReaderFromBuf(b)
tx.DecodeBinary(r)
assert.Nil(t, r.Err)
assert.Equal(t, RegisterType, tx.Type) assert.Equal(t, RegisterType, tx.Type)
txData := tx.Data.(*RegisterTX) txData := tx.Data.(*RegisterTX)
assert.Equal(t, GoverningToken, txData.AssetType) assert.Equal(t, GoverningToken, txData.AssetType)
@ -58,10 +63,13 @@ func TestDecodeRegisterTXFromRawString(t *testing.T) {
assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().ReverseString()) assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().ReverseString())
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
assert.Nil(t, tx.EncodeBinary(buf.BinWriter)) tx.EncodeBinary(buf.BinWriter)
assert.Nil(t, buf.Err)
benc := buf.Bytes() benc := buf.Bytes()
txDecode := &Transaction{} txDecode := &Transaction{}
assert.Nil(t, txDecode.DecodeBinary(io.NewBinReaderFromBuf(benc))) encreader := io.NewBinReaderFromBuf(benc)
txDecode.DecodeBinary(encreader)
assert.Nil(t, encreader.Err)
assert.Equal(t, tx, txDecode) assert.Equal(t, tx, txDecode)
} }

View file

@ -9,28 +9,20 @@ type StateTX struct {
Descriptors []*StateDescriptor Descriptors []*StateDescriptor
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (tx *StateTX) DecodeBinary(r *io.BinReader) error { func (tx *StateTX) DecodeBinary(r *io.BinReader) {
lenDesc := r.ReadVarUint() lenDesc := r.ReadVarUint()
tx.Descriptors = make([]*StateDescriptor, lenDesc) tx.Descriptors = make([]*StateDescriptor, lenDesc)
for i := 0; i < int(lenDesc); i++ { for i := 0; i < int(lenDesc); i++ {
tx.Descriptors[i] = &StateDescriptor{} tx.Descriptors[i] = &StateDescriptor{}
err := tx.Descriptors[i].DecodeBinary(r) tx.Descriptors[i].DecodeBinary(r)
if err != nil {
return err
}
} }
return r.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (tx *StateTX) EncodeBinary(w *io.BinWriter) error { func (tx *StateTX) EncodeBinary(w *io.BinWriter) {
w.WriteVarUint(uint64(len(tx.Descriptors))) w.WriteVarUint(uint64(len(tx.Descriptors)))
for _, desc := range tx.Descriptors { for _, desc := range tx.Descriptors {
err := desc.EncodeBinary(w) desc.EncodeBinary(w)
if err != nil {
return err
}
} }
return w.Err
} }

View file

@ -21,22 +21,19 @@ type StateDescriptor struct {
Field string Field string
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (s *StateDescriptor) DecodeBinary(r *io.BinReader) error { func (s *StateDescriptor) DecodeBinary(r *io.BinReader) {
r.ReadLE(&s.Type) r.ReadLE(&s.Type)
s.Key = r.ReadBytes() s.Key = r.ReadBytes()
s.Value = r.ReadBytes() s.Value = r.ReadBytes()
s.Field = r.ReadString() s.Field = r.ReadString()
return r.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (s *StateDescriptor) EncodeBinary(w *io.BinWriter) error { func (s *StateDescriptor) EncodeBinary(w *io.BinWriter) {
w.WriteLE(s.Type) w.WriteLE(s.Type)
w.WriteBytes(s.Key) w.WriteBytes(s.Key)
w.WriteBytes(s.Value) w.WriteBytes(s.Value)
w.WriteString(s.Field) w.WriteString(s.Field)
return w.Err
} }

View file

@ -31,9 +31,8 @@ func TestEncodeDecodeState(t *testing.T) {
// Encode // Encode
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
tx.EncodeBinary(buf.BinWriter)
err := tx.EncodeBinary(buf.BinWriter) assert.Equal(t, nil, buf.Err)
assert.Equal(t, nil, err)
assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes()))
} }

View file

@ -74,170 +74,126 @@ func (t *Transaction) AddInput(in *Input) {
t.Inputs = append(t.Inputs, in) t.Inputs = append(t.Inputs, in)
} }
// DecodeBinary implements the payload interface. // DecodeBinary implements Serializable interface.
func (t *Transaction) DecodeBinary(br *io.BinReader) error { func (t *Transaction) DecodeBinary(br *io.BinReader) {
br.ReadLE(&t.Type) br.ReadLE(&t.Type)
br.ReadLE(&t.Version) br.ReadLE(&t.Version)
if br.Err != nil { t.decodeData(br)
return br.Err
}
if err := t.decodeData(br); err != nil {
return err
}
lenAttrs := br.ReadVarUint() lenAttrs := br.ReadVarUint()
t.Attributes = make([]*Attribute, lenAttrs) t.Attributes = make([]*Attribute, lenAttrs)
for i := 0; i < int(lenAttrs); i++ { for i := 0; i < int(lenAttrs); i++ {
t.Attributes[i] = &Attribute{} t.Attributes[i] = &Attribute{}
if err := t.Attributes[i].DecodeBinary(br); err != nil { t.Attributes[i].DecodeBinary(br)
log.Warnf("failed to decode TX %s", t.hash)
return err
}
} }
lenInputs := br.ReadVarUint() lenInputs := br.ReadVarUint()
t.Inputs = make([]*Input, lenInputs) t.Inputs = make([]*Input, lenInputs)
for i := 0; i < int(lenInputs); i++ { for i := 0; i < int(lenInputs); i++ {
t.Inputs[i] = &Input{} t.Inputs[i] = &Input{}
if err := t.Inputs[i].DecodeBinary(br); err != nil { t.Inputs[i].DecodeBinary(br)
return err
}
} }
lenOutputs := br.ReadVarUint() lenOutputs := br.ReadVarUint()
t.Outputs = make([]*Output, lenOutputs) t.Outputs = make([]*Output, lenOutputs)
for i := 0; i < int(lenOutputs); i++ { for i := 0; i < int(lenOutputs); i++ {
t.Outputs[i] = &Output{} t.Outputs[i] = &Output{}
if err := t.Outputs[i].DecodeBinary(br); err != nil { t.Outputs[i].DecodeBinary(br)
return err
}
} }
lenScripts := br.ReadVarUint() lenScripts := br.ReadVarUint()
t.Scripts = make([]*Witness, lenScripts) t.Scripts = make([]*Witness, lenScripts)
for i := 0; i < int(lenScripts); i++ { for i := 0; i < int(lenScripts); i++ {
t.Scripts[i] = &Witness{} t.Scripts[i] = &Witness{}
if err := t.Scripts[i].DecodeBinary(br); err != nil { t.Scripts[i].DecodeBinary(br)
return err
}
} }
if br.Err != nil {
return br.Err
}
// Create the hash of the transaction at decode, so we dont need // Create the hash of the transaction at decode, so we dont need
// to do it anymore. // to do it anymore.
return t.createHash() if br.Err == nil {
br.Err = t.createHash()
}
} }
func (t *Transaction) decodeData(r *io.BinReader) error { func (t *Transaction) decodeData(r *io.BinReader) {
switch t.Type { switch t.Type {
case InvocationType: case InvocationType:
t.Data = &InvocationTX{Version: t.Version} t.Data = &InvocationTX{Version: t.Version}
return t.Data.(*InvocationTX).DecodeBinary(r) t.Data.(*InvocationTX).DecodeBinary(r)
case MinerType: case MinerType:
t.Data = &MinerTX{} t.Data = &MinerTX{}
return t.Data.(*MinerTX).DecodeBinary(r) t.Data.(*MinerTX).DecodeBinary(r)
case ClaimType: case ClaimType:
t.Data = &ClaimTX{} t.Data = &ClaimTX{}
return t.Data.(*ClaimTX).DecodeBinary(r) t.Data.(*ClaimTX).DecodeBinary(r)
case ContractType: case ContractType:
t.Data = &ContractTX{} t.Data = &ContractTX{}
return t.Data.(*ContractTX).DecodeBinary(r) t.Data.(*ContractTX).DecodeBinary(r)
case RegisterType: case RegisterType:
t.Data = &RegisterTX{} t.Data = &RegisterTX{}
return t.Data.(*RegisterTX).DecodeBinary(r) t.Data.(*RegisterTX).DecodeBinary(r)
case IssueType: case IssueType:
t.Data = &IssueTX{} t.Data = &IssueTX{}
return t.Data.(*IssueTX).DecodeBinary(r) t.Data.(*IssueTX).DecodeBinary(r)
case EnrollmentType: case EnrollmentType:
t.Data = &EnrollmentTX{} t.Data = &EnrollmentTX{}
return t.Data.(*EnrollmentTX).DecodeBinary(r) t.Data.(*EnrollmentTX).DecodeBinary(r)
case PublishType: case PublishType:
t.Data = &PublishTX{Version: t.Version} t.Data = &PublishTX{Version: t.Version}
return t.Data.(*PublishTX).DecodeBinary(r) t.Data.(*PublishTX).DecodeBinary(r)
case StateType: case StateType:
t.Data = &StateTX{} t.Data = &StateTX{}
return t.Data.(*StateTX).DecodeBinary(r) t.Data.(*StateTX).DecodeBinary(r)
default: default:
log.Warnf("invalid TX type %s", t.Type) log.Warnf("invalid TX type %s", t.Type)
} }
return nil
} }
// EncodeBinary implements the payload interface. // EncodeBinary implements Serializable interface.
func (t *Transaction) EncodeBinary(bw *io.BinWriter) error { func (t *Transaction) EncodeBinary(bw *io.BinWriter) {
if err := t.encodeHashableFields(bw); err != nil { t.encodeHashableFields(bw)
return err
}
bw.WriteVarUint(uint64(len(t.Scripts))) bw.WriteVarUint(uint64(len(t.Scripts)))
if bw.Err != nil {
return bw.Err
}
for _, s := range t.Scripts { for _, s := range t.Scripts {
if err := s.EncodeBinary(bw); err != nil { s.EncodeBinary(bw)
return err
}
} }
return nil
} }
// encodeHashableFields will only encode the fields that are not used for // encodeHashableFields will only encode the fields that are not used for
// signing the transaction, which are all fields except the scripts. // signing the transaction, which are all fields except the scripts.
func (t *Transaction) encodeHashableFields(bw *io.BinWriter) error { func (t *Transaction) encodeHashableFields(bw *io.BinWriter) {
bw.WriteLE(t.Type) bw.WriteLE(t.Type)
bw.WriteLE(t.Version) bw.WriteLE(t.Version)
if bw.Err != nil {
return bw.Err
}
// Underlying TXer. // Underlying TXer.
if t.Data != nil { if t.Data != nil {
if err := t.Data.EncodeBinary(bw); err != nil { t.Data.EncodeBinary(bw)
return err
}
} }
// Attributes // Attributes
bw.WriteVarUint(uint64(len(t.Attributes))) bw.WriteVarUint(uint64(len(t.Attributes)))
if bw.Err != nil {
return bw.Err
}
for _, attr := range t.Attributes { for _, attr := range t.Attributes {
if err := attr.EncodeBinary(bw); err != nil { attr.EncodeBinary(bw)
return err
}
} }
// Inputs // Inputs
bw.WriteVarUint(uint64(len(t.Inputs))) bw.WriteVarUint(uint64(len(t.Inputs)))
if bw.Err != nil {
return bw.Err
}
for _, in := range t.Inputs { for _, in := range t.Inputs {
if err := in.EncodeBinary(bw); err != nil { in.EncodeBinary(bw)
return err
}
} }
// Outputs // Outputs
bw.WriteVarUint(uint64(len(t.Outputs))) bw.WriteVarUint(uint64(len(t.Outputs)))
if bw.Err != nil {
return bw.Err
}
for _, out := range t.Outputs { for _, out := range t.Outputs {
if err := out.EncodeBinary(bw); err != nil { out.EncodeBinary(bw)
return err
}
} }
return nil
} }
// createHash creates the hash of the transaction. // createHash creates the hash of the transaction.
func (t *Transaction) createHash() error { func (t *Transaction) createHash() error {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
if err := t.encodeHashableFields(buf.BinWriter); err != nil { t.encodeHashableFields(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
t.hash = hash.DoubleSha256(buf.Bytes()) t.hash = hash.DoubleSha256(buf.Bytes())
@ -266,9 +222,9 @@ func (t Transaction) GroupOutputByAssetID() map[util.Uint256][]*Output {
// Bytes convert the transaction to []byte // Bytes convert the transaction to []byte
func (t *Transaction) Bytes() []byte { func (t *Transaction) Bytes() []byte {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
if err := t.EncodeBinary(buf.BinWriter); err != nil { t.EncodeBinary(buf.BinWriter)
if buf.Err != nil {
return nil return nil
} }
return buf.Bytes() return buf.Bytes()
} }

View file

@ -28,13 +28,14 @@ func TestWitnessEncodeDecode(t *testing.T) {
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err = wit.EncodeBinary(buf.BinWriter) wit.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
benc := buf.Bytes() benc := buf.Bytes()
witDecode := &Witness{} witDecode := &Witness{}
err = witDecode.DecodeBinary(io.NewBinReaderFromBuf(benc)) encreader := io.NewBinReaderFromBuf(benc)
assert.Nil(t, err) witDecode.DecodeBinary(encreader)
assert.Nil(t, encreader.Err)
t.Log(len(witDecode.VerificationScript)) t.Log(len(witDecode.VerificationScript))
t.Log(len(witDecode.InvocationScript)) t.Log(len(witDecode.InvocationScript))
@ -61,8 +62,8 @@ func TestDecodeEncodeClaimTX(t *testing.T) {
assert.Equal(t, verif, hex.EncodeToString(tx.Scripts[0].VerificationScript)) assert.Equal(t, verif, hex.EncodeToString(tx.Scripts[0].VerificationScript))
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := tx.EncodeBinary(buf.BinWriter) tx.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
assert.Equal(t, rawClaimTX, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawClaimTX, hex.EncodeToString(buf.Bytes()))
hash := "2c6a45547b3898318e400e541628990a07acb00f3b9a15a8e966ae49525304da" hash := "2c6a45547b3898318e400e541628990a07acb00f3b9a15a8e966ae49525304da"
@ -89,8 +90,8 @@ func TestDecodeEncodeInvocationTX(t *testing.T) {
assert.Equal(t, verif, hex.EncodeToString(tx.Scripts[0].VerificationScript)) assert.Equal(t, verif, hex.EncodeToString(tx.Scripts[0].VerificationScript))
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := tx.EncodeBinary(buf.BinWriter) tx.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
assert.Equal(t, rawInvocationTX, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawInvocationTX, hex.EncodeToString(buf.Bytes()))
} }
@ -144,7 +145,7 @@ func TestDecodePublishTX(t *testing.T) {
assert.Equal(t, expectedTX.Version, actualTX.Version) assert.Equal(t, expectedTX.Version, actualTX.Version)
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := actualTX.EncodeBinary(buf.BinWriter) actualTX.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
assert.Equal(t, rawPublishTX, hex.EncodeToString(buf.Bytes())) assert.Equal(t, rawPublishTX, hex.EncodeToString(buf.Bytes()))
} }

View file

@ -15,19 +15,16 @@ type Witness struct {
VerificationScript []byte VerificationScript []byte
} }
// DecodeBinary implements the payload interface. // DecodeBinary implements Serializable interface.
func (w *Witness) DecodeBinary(br *io.BinReader) error { func (w *Witness) DecodeBinary(br *io.BinReader) {
w.InvocationScript = br.ReadBytes() w.InvocationScript = br.ReadBytes()
w.VerificationScript = br.ReadBytes() w.VerificationScript = br.ReadBytes()
return br.Err
} }
// EncodeBinary implements the payload interface. // EncodeBinary implements Serializable interface.
func (w *Witness) EncodeBinary(bw *io.BinWriter) error { func (w *Witness) EncodeBinary(bw *io.BinWriter) {
bw.WriteBytes(w.InvocationScript) bw.WriteBytes(w.InvocationScript)
bw.WriteBytes(w.VerificationScript) bw.WriteBytes(w.VerificationScript)
return bw.Err
} }
// MarshalJSON implements the json marshaller interface. // MarshalJSON implements the json marshaller interface.

View file

@ -21,8 +21,10 @@ func (u UnspentCoins) getAndUpdate(s storage.Store, hash util.Uint256) (*Unspent
unspent := &UnspentCoinState{} unspent := &UnspentCoinState{}
key := storage.AppendPrefix(storage.STCoin, hash.BytesReverse()) key := storage.AppendPrefix(storage.STCoin, hash.BytesReverse())
if b, err := s.Get(key); err == nil { if b, err := s.Get(key); err == nil {
if err := unspent.DecodeBinary(io.NewBinReaderFromBuf(b)); err != nil { r := io.NewBinReaderFromBuf(b)
return nil, fmt.Errorf("failed to decode (UnspentCoinState): %s", err) unspent.DecodeBinary(r)
if r.Err != nil {
return nil, fmt.Errorf("failed to decode (UnspentCoinState): %s", r.Err)
} }
} else { } else {
unspent = &UnspentCoinState{ unspent = &UnspentCoinState{
@ -54,8 +56,9 @@ func NewUnspentCoinState(n int) *UnspentCoinState {
func (u UnspentCoins) commit(b storage.Batch) error { func (u UnspentCoins) commit(b storage.Batch) error {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
for hash, state := range u { for hash, state := range u {
if err := state.EncodeBinary(buf.BinWriter); err != nil { state.EncodeBinary(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
key := storage.AppendPrefix(storage.STCoin, hash.BytesReverse()) key := storage.AppendPrefix(storage.STCoin, hash.BytesReverse())
b.Put(key, buf.Bytes()) b.Put(key, buf.Bytes())
@ -65,16 +68,15 @@ func (u UnspentCoins) commit(b storage.Batch) error {
} }
// EncodeBinary encodes UnspentCoinState to the given BinWriter. // EncodeBinary encodes UnspentCoinState to the given BinWriter.
func (s *UnspentCoinState) EncodeBinary(bw *io.BinWriter) error { func (s *UnspentCoinState) EncodeBinary(bw *io.BinWriter) {
bw.WriteVarUint(uint64(len(s.states))) bw.WriteVarUint(uint64(len(s.states)))
for _, state := range s.states { for _, state := range s.states {
bw.WriteLE(byte(state)) bw.WriteLE(byte(state))
} }
return bw.Err
} }
// DecodeBinary decodes UnspentCoinState from the given BinReader. // DecodeBinary decodes UnspentCoinState from the given BinReader.
func (s *UnspentCoinState) DecodeBinary(br *io.BinReader) error { func (s *UnspentCoinState) DecodeBinary(br *io.BinReader) {
lenStates := br.ReadVarUint() lenStates := br.ReadVarUint()
s.states = make([]CoinState, lenStates) s.states = make([]CoinState, lenStates)
for i := 0; i < int(lenStates); i++ { for i := 0; i < int(lenStates); i++ {
@ -82,7 +84,6 @@ func (s *UnspentCoinState) DecodeBinary(br *io.BinReader) error {
br.ReadLE(&state) br.ReadLE(&state)
s.states[i] = CoinState(state) s.states[i] = CoinState(state)
} }
return br.Err
} }
// IsDoubleSpend verifies that the input transactions are not double spent. // IsDoubleSpend verifies that the input transactions are not double spent.
@ -95,7 +96,9 @@ func IsDoubleSpend(s storage.Store, tx *transaction.Transaction) bool {
unspent := &UnspentCoinState{} unspent := &UnspentCoinState{}
key := storage.AppendPrefix(storage.STCoin, prevHash.BytesReverse()) key := storage.AppendPrefix(storage.STCoin, prevHash.BytesReverse())
if b, err := s.Get(key); err == nil { if b, err := s.Get(key); err == nil {
if err := unspent.DecodeBinary(io.NewBinReaderFromBuf(b)); err != nil { r := io.NewBinReaderFromBuf(b)
unspent.DecodeBinary(r)
if r.Err != nil {
return false return false
} }
if unspent == nil { if unspent == nil {

View file

@ -20,9 +20,12 @@ func TestDecodeEncodeUnspentCoinState(t *testing.T) {
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
assert.Nil(t, unspent.EncodeBinary(buf.BinWriter)) unspent.EncodeBinary(buf.BinWriter)
assert.Nil(t, buf.Err)
unspentDecode := &UnspentCoinState{} unspentDecode := &UnspentCoinState{}
assert.Nil(t, unspentDecode.DecodeBinary(io.NewBinReaderFromBuf(buf.Bytes()))) r := io.NewBinReaderFromBuf(buf.Bytes())
unspentDecode.DecodeBinary(r)
assert.Nil(t, r.Err)
} }
func TestCommitUnspentCoins(t *testing.T) { func TestCommitUnspentCoins(t *testing.T) {

View file

@ -211,11 +211,10 @@ func storeAsTransaction(batch storage.Batch, tx *transaction.Transaction, index
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesReverse()) key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesReverse())
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
buf.WriteLE(index) buf.WriteLE(index)
if err := tx.EncodeBinary(buf.BinWriter); err != nil { tx.EncodeBinary(buf.BinWriter)
return err if buf.Err != nil {
return buf.Err
} }
batch.Put(key, buf.Bytes()) batch.Put(key, buf.Bytes())
return nil return nil
} }

View file

@ -50,8 +50,10 @@ func NewPublicKeyFromString(s string) (*PublicKey, error) {
} }
pubKey := new(PublicKey) pubKey := new(PublicKey)
if err := pubKey.DecodeBinary(io.NewBinReaderFromBuf(b)); err != nil { r := io.NewBinReaderFromBuf(b)
return nil, err pubKey.DecodeBinary(r)
if r.Err != nil {
return nil, r.Err
} }
return pubKey, nil return pubKey, nil
@ -122,37 +124,38 @@ func decodeCompressedY(x *big.Int, ylsb uint) (*big.Int, error) {
// DecodeBytes decodes a PublicKey from the given slice of bytes. // DecodeBytes decodes a PublicKey from the given slice of bytes.
func (p *PublicKey) DecodeBytes(data []byte) error { func (p *PublicKey) DecodeBytes(data []byte) error {
b := io.NewBinReaderFromBuf(data) b := io.NewBinReaderFromBuf(data)
return p.DecodeBinary(b) p.DecodeBinary(b)
return b.Err
} }
// DecodeBinary decodes a PublicKey from the given BinReader. // DecodeBinary decodes a PublicKey from the given BinReader.
func (p *PublicKey) DecodeBinary(r *io.BinReader) error { func (p *PublicKey) DecodeBinary(r *io.BinReader) {
var prefix uint8 var prefix uint8
var x, y *big.Int var x, y *big.Int
var err error var err error
r.ReadLE(&prefix) r.ReadLE(&prefix)
if r.Err != nil { if r.Err != nil {
return r.Err return
} }
// Infinity // Infinity
switch prefix { switch prefix {
case 0x00: case 0x00:
// noop, initialized to nil // noop, initialized to nil
return nil return
case 0x02, 0x03: case 0x02, 0x03:
// Compressed public keys // Compressed public keys
xbytes := make([]byte, 32) xbytes := make([]byte, 32)
r.ReadLE(xbytes) r.ReadLE(xbytes)
if r.Err != nil { if r.Err != nil {
return r.Err return
} }
x = new(big.Int).SetBytes(xbytes) x = new(big.Int).SetBytes(xbytes)
ylsb := uint(prefix & 0x1) ylsb := uint(prefix & 0x1)
y, err = decodeCompressedY(x, ylsb) y, err = decodeCompressedY(x, ylsb)
if err != nil { if err != nil {
return err return
} }
case 0x04: case 0x04:
xbytes := make([]byte, 32) xbytes := make([]byte, 32)
@ -160,30 +163,30 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) error {
r.ReadLE(xbytes) r.ReadLE(xbytes)
r.ReadLE(ybytes) r.ReadLE(ybytes)
if r.Err != nil { if r.Err != nil {
return r.Err return
} }
x = new(big.Int).SetBytes(xbytes) x = new(big.Int).SetBytes(xbytes)
y = new(big.Int).SetBytes(ybytes) y = new(big.Int).SetBytes(ybytes)
default: default:
return errors.Errorf("invalid prefix %d", prefix) r.Err = errors.Errorf("invalid prefix %d", prefix)
return
} }
c := elliptic.P256() c := elliptic.P256()
cp := c.Params() cp := c.Params()
if !c.IsOnCurve(x, y) { if !c.IsOnCurve(x, y) {
return errors.New("enccoded point is not on the P256 curve") r.Err = errors.New("enccoded point is not on the P256 curve")
return
} }
if x.Cmp(cp.P) >= 0 || y.Cmp(cp.P) >= 0 { if x.Cmp(cp.P) >= 0 || y.Cmp(cp.P) >= 0 {
return errors.New("enccoded point is not correct (X or Y is bigger than P") r.Err = errors.New("enccoded point is not correct (X or Y is bigger than P")
return
} }
p.X, p.Y = x, y p.X, p.Y = x, y
return nil
} }
// EncodeBinary encodes a PublicKey to the given BinWriter. // EncodeBinary encodes a PublicKey to the given BinWriter.
func (p *PublicKey) EncodeBinary(w *io.BinWriter) error { func (p *PublicKey) EncodeBinary(w *io.BinWriter) {
w.WriteLE(p.Bytes()) w.WriteLE(p.Bytes())
return w.Err
} }
// Signature returns a NEO-specific hash of the key. // Signature returns a NEO-specific hash of the key.

View file

@ -11,7 +11,7 @@ import (
func TestEncodeDecodeInfinity(t *testing.T) { func TestEncodeDecodeInfinity(t *testing.T) {
key := &PublicKey{} key := &PublicKey{}
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
assert.Nil(t, key.EncodeBinary(buf.BinWriter)) key.EncodeBinary(buf.BinWriter)
assert.Nil(t, buf.Err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
assert.Equal(t, 1, len(b)) assert.Equal(t, 1, len(b))
@ -27,7 +27,7 @@ func TestEncodeDecodePublicKey(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
p := k.PublicKey() p := k.PublicKey()
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
assert.Nil(t, p.EncodeBinary(buf.BinWriter)) p.EncodeBinary(buf.BinWriter)
assert.Nil(t, buf.Err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()

View file

@ -1,7 +1,12 @@
package io package io
// Serializable defines the binary encoding/decoding interface. // Serializable defines the binary encoding/decoding interface. Errors are
// returned via BinReader/BinWriter Err field. These functions must have safe
// behavior when passed BinReader/BinWriter with Err already set. Invocations
// to these functions tend to be nested, with this mechanism only the top-level
// caller should handle the error once and all the other code should just not
// panic in presence of error.
type Serializable interface { type Serializable interface {
DecodeBinary(*BinReader) error DecodeBinary(*BinReader)
EncodeBinary(*BinWriter) error EncodeBinary(*BinWriter)
} }

View file

@ -80,9 +80,9 @@ func GetVarSize(value interface{}) int {
} }
cw := counterWriter{} cw := counterWriter{}
w := NewBinWriterFromIO(&cw) w := NewBinWriterFromIO(&cw)
err := vser.EncodeBinary(w) vser.EncodeBinary(w)
if err != nil { if w.Err != nil {
panic(fmt.Sprintf("error serializing %s: %s", reflect.TypeOf(value), err.Error())) panic(fmt.Sprintf("error serializing %s: %s", reflect.TypeOf(value), w.Err.Error()))
} }
return cw.counter return cw.counter
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:

View file

@ -13,13 +13,10 @@ type smthSerializable struct {
some [42]byte some [42]byte
} }
func (*smthSerializable) DecodeBinary(*BinReader) error { func (*smthSerializable) DecodeBinary(*BinReader) {}
return nil
}
func (ss *smthSerializable) EncodeBinary(bw *BinWriter) error { func (ss *smthSerializable) EncodeBinary(bw *BinWriter) {
bw.WriteLE(ss.some) bw.WriteLE(ss.some)
return nil
} }
func TestVarSize(t *testing.T) { func TestVarSize(t *testing.T) {

View file

@ -78,8 +78,9 @@ func NewMessage(magic config.NetMode, cmd CommandType, p payload.Payload) *Messa
if p != nil { if p != nil {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
if err := p.EncodeBinary(buf.BinWriter); err != nil { p.EncodeBinary(buf.BinWriter)
panic(err) if buf.Err != nil {
panic(buf.Err)
} }
b := buf.Bytes() b := buf.Bytes()
size = uint32(len(b)) size = uint32(len(b))
@ -176,46 +177,26 @@ func (m *Message) decodePayload(br *io.BinReader) error {
switch m.CommandType() { switch m.CommandType() {
case CMDVersion: case CMDVersion:
p = &payload.Version{} p = &payload.Version{}
if err := p.DecodeBinary(r); err != nil {
return err
}
case CMDInv, CMDGetData: case CMDInv, CMDGetData:
p = &payload.Inventory{} p = &payload.Inventory{}
if err := p.DecodeBinary(r); err != nil {
return err
}
case CMDAddr: case CMDAddr:
p = &payload.AddressList{} p = &payload.AddressList{}
if err := p.DecodeBinary(r); err != nil {
return err
}
case CMDBlock: case CMDBlock:
p = &core.Block{} p = &core.Block{}
if err := p.DecodeBinary(r); err != nil {
return err
}
case CMDGetBlocks: case CMDGetBlocks:
fallthrough fallthrough
case CMDGetHeaders: case CMDGetHeaders:
p = &payload.GetBlocks{} p = &payload.GetBlocks{}
if err := p.DecodeBinary(r); err != nil {
return err
}
case CMDHeaders: case CMDHeaders:
p = &payload.Headers{} p = &payload.Headers{}
if err := p.DecodeBinary(r); err != nil {
return err
}
case CMDTX: case CMDTX:
p = &transaction.Transaction{} p = &transaction.Transaction{}
if err := p.DecodeBinary(r); err != nil {
return err
}
case CMDMerkleBlock: case CMDMerkleBlock:
p = &payload.MerkleBlock{} p = &payload.MerkleBlock{}
if err := p.DecodeBinary(r); err != nil { }
return err p.DecodeBinary(r)
} if r.Err != nil {
return r.Err
} }
m.Payload = p m.Payload = p
@ -229,12 +210,13 @@ func (m *Message) Encode(br *io.BinWriter) error {
br.WriteLE(m.Command) br.WriteLE(m.Command)
br.WriteLE(m.Length) br.WriteLE(m.Length)
br.WriteLE(m.Checksum) br.WriteLE(m.Checksum)
if m.Payload != nil {
m.Payload.EncodeBinary(br)
}
if br.Err != nil { if br.Err != nil {
return br.Err return br.Err
} }
if m.Payload != nil {
return m.Payload.EncodeBinary(br)
}
return nil return nil
} }

View file

@ -27,22 +27,20 @@ func NewAddressAndTime(e *net.TCPAddr, t time.Time) *AddressAndTime {
return &aat return &aat
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (p *AddressAndTime) DecodeBinary(br *io.BinReader) error { func (p *AddressAndTime) DecodeBinary(br *io.BinReader) {
br.ReadLE(&p.Timestamp) br.ReadLE(&p.Timestamp)
br.ReadLE(&p.Services) br.ReadLE(&p.Services)
br.ReadBE(&p.IP) br.ReadBE(&p.IP)
br.ReadBE(&p.Port) br.ReadBE(&p.Port)
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (p *AddressAndTime) EncodeBinary(bw *io.BinWriter) error { func (p *AddressAndTime) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(p.Timestamp) bw.WriteLE(p.Timestamp)
bw.WriteLE(p.Services) bw.WriteLE(p.Services)
bw.WriteBE(p.IP) bw.WriteBE(p.IP)
bw.WriteBE(p.Port) bw.WriteBE(p.Port)
return bw.Err
} }
// IPPortString makes a string from IP and port specified. // IPPortString makes a string from IP and port specified.
@ -67,33 +65,21 @@ func NewAddressList(n int) *AddressList {
return &alist return &alist
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (p *AddressList) DecodeBinary(br *io.BinReader) error { func (p *AddressList) DecodeBinary(br *io.BinReader) {
listLen := br.ReadVarUint() listLen := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
p.Addrs = make([]*AddressAndTime, listLen) p.Addrs = make([]*AddressAndTime, listLen)
for i := 0; i < int(listLen); i++ { for i := 0; i < int(listLen); i++ {
p.Addrs[i] = &AddressAndTime{} p.Addrs[i] = &AddressAndTime{}
if err := p.Addrs[i].DecodeBinary(br); err != nil { p.Addrs[i].DecodeBinary(br)
return err
}
} }
return nil
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (p *AddressList) EncodeBinary(bw *io.BinWriter) error { func (p *AddressList) EncodeBinary(bw *io.BinWriter) {
bw.WriteVarUint(uint64(len(p.Addrs))) bw.WriteVarUint(uint64(len(p.Addrs)))
if bw.Err != nil {
return bw.Err
}
for _, addr := range p.Addrs { for _, addr := range p.Addrs {
if err := addr.EncodeBinary(bw); err != nil { addr.EncodeBinary(bw)
return err
}
} }
return nil
} }

View file

@ -23,14 +23,14 @@ func TestEncodeDecodeAddress(t *testing.T) {
copy(aatip, addr.IP[:]) copy(aatip, addr.IP[:])
assert.Equal(t, e.IP, aatip) assert.Equal(t, e.IP, aatip)
assert.Equal(t, e.Port, int(addr.Port)) assert.Equal(t, e.Port, int(addr.Port))
err := addr.EncodeBinary(buf.BinWriter) addr.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
addrDecode := &AddressAndTime{} addrDecode := &AddressAndTime{}
err = addrDecode.DecodeBinary(r) addrDecode.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
assert.Equal(t, addr, addrDecode) assert.Equal(t, addr, addrDecode)
} }
@ -44,14 +44,14 @@ func TestEncodeDecodeAddressList(t *testing.T) {
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := addrList.EncodeBinary(buf.BinWriter) addrList.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
addrListDecode := &AddressList{} addrListDecode := &AddressList{}
err = addrListDecode.DecodeBinary(r) addrListDecode.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
assert.Equal(t, addrList, addrListDecode) assert.Equal(t, addrList, addrListDecode)
} }

View file

@ -21,20 +21,18 @@ func NewGetBlocks(start []util.Uint256, stop util.Uint256) *GetBlocks {
} }
} }
// DecodeBinary implements the payload interface. // DecodeBinary implements Serializable interface.
func (p *GetBlocks) DecodeBinary(br *io.BinReader) error { func (p *GetBlocks) DecodeBinary(br *io.BinReader) {
lenStart := br.ReadVarUint() lenStart := br.ReadVarUint()
p.HashStart = make([]util.Uint256, lenStart) p.HashStart = make([]util.Uint256, lenStart)
br.ReadLE(&p.HashStart) br.ReadLE(&p.HashStart)
br.ReadLE(&p.HashStop) br.ReadLE(&p.HashStop)
return br.Err
} }
// EncodeBinary implements the payload interface. // EncodeBinary implements Serializable interface.
func (p *GetBlocks) EncodeBinary(bw *io.BinWriter) error { func (p *GetBlocks) EncodeBinary(bw *io.BinWriter) {
bw.WriteVarUint(uint64(len(p.HashStart))) bw.WriteVarUint(uint64(len(p.HashStart)))
bw.WriteLE(p.HashStart) bw.WriteLE(p.HashStart)
bw.WriteLE(p.HashStop) bw.WriteLE(p.HashStop)
return bw.Err
} }

View file

@ -19,14 +19,14 @@ func TestGetBlockEncodeDecode(t *testing.T) {
p := NewGetBlocks(start, util.Uint256{}) p := NewGetBlocks(start, util.Uint256{})
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := p.EncodeBinary(buf.BinWriter) p.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
pDecode := &GetBlocks{} pDecode := &GetBlocks{}
err = pDecode.DecodeBinary(r) pDecode.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
assert.Equal(t, p, pDecode) assert.Equal(t, p, pDecode)
} }
@ -42,13 +42,13 @@ func TestGetBlockEncodeDecodeWithHashStop(t *testing.T) {
) )
p := NewGetBlocks(start, stop) p := NewGetBlocks(start, stop)
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := p.EncodeBinary(buf.BinWriter) p.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
pDecode := &GetBlocks{} pDecode := &GetBlocks{}
err = pDecode.DecodeBinary(r) pDecode.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
assert.Equal(t, p, pDecode) assert.Equal(t, p, pDecode)
} }

View file

@ -16,12 +16,10 @@ const (
maxHeadersAllowed = 2000 maxHeadersAllowed = 2000
) )
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (p *Headers) DecodeBinary(br *io.BinReader) error { func (p *Headers) DecodeBinary(br *io.BinReader) {
lenHeaders := br.ReadVarUint() lenHeaders := br.ReadVarUint()
if br.Err != nil {
return br.Err
}
// C# node does it silently // C# node does it silently
if lenHeaders > maxHeadersAllowed { if lenHeaders > maxHeadersAllowed {
log.Warnf("received %d headers, capping to %d", lenHeaders, maxHeadersAllowed) log.Warnf("received %d headers, capping to %d", lenHeaders, maxHeadersAllowed)
@ -32,26 +30,16 @@ func (p *Headers) DecodeBinary(br *io.BinReader) error {
for i := 0; i < int(lenHeaders); i++ { for i := 0; i < int(lenHeaders); i++ {
header := &core.Header{} header := &core.Header{}
if err := header.DecodeBinary(br); err != nil { header.DecodeBinary(br)
return err
}
p.Hdrs[i] = header p.Hdrs[i] = header
} }
return nil
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (p *Headers) EncodeBinary(bw *io.BinWriter) error { func (p *Headers) EncodeBinary(bw *io.BinWriter) {
bw.WriteVarUint(uint64(len(p.Hdrs))) bw.WriteVarUint(uint64(len(p.Hdrs)))
if bw.Err != nil {
return bw.Err
}
for _, header := range p.Hdrs { for _, header := range p.Hdrs {
if err := header.EncodeBinary(bw); err != nil { header.EncodeBinary(bw)
return err
}
} }
return nil
} }

View file

@ -42,14 +42,14 @@ func TestHeadersEncodeDecode(t *testing.T) {
}} }}
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := headers.EncodeBinary(buf.BinWriter) headers.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
headersDecode := &Headers{} headersDecode := &Headers{}
err = headersDecode.DecodeBinary(r) headersDecode.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
for i := 0; i < len(headers.Hdrs); i++ { for i := 0; i < len(headers.Hdrs); i++ {
assert.Equal(t, headers.Hdrs[i].Version, headersDecode.Hdrs[i].Version) assert.Equal(t, headers.Hdrs[i].Version, headersDecode.Hdrs[i].Version)
@ -67,8 +67,8 @@ func TestBinEncodeDecode(t *testing.T) {
r := io.NewBinReaderFromBuf(rawBlockBytes) r := io.NewBinReaderFromBuf(rawBlockBytes)
err := headerMsg.DecodeBinary(r) headerMsg.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
assert.Equal(t, 1, len(headerMsg.Hdrs)) assert.Equal(t, 1, len(headerMsg.Hdrs))
header := headerMsg.Hdrs[0] header := headerMsg.Hdrs[0]
@ -78,7 +78,7 @@ func TestBinEncodeDecode(t *testing.T) {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err = headerMsg.EncodeBinary(buf.BinWriter) headerMsg.EncodeBinary(buf.BinWriter)
assert.Equal(t, nil, err) assert.Equal(t, nil, buf.Err)
assert.Equal(t, hex.EncodeToString(rawBlockBytes), hex.EncodeToString(buf.Bytes())) assert.Equal(t, hex.EncodeToString(rawBlockBytes), hex.EncodeToString(buf.Bytes()))
} }

View file

@ -54,8 +54,8 @@ func NewInventory(typ InventoryType, hashes []util.Uint256) *Inventory {
} }
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (p *Inventory) DecodeBinary(br *io.BinReader) error { func (p *Inventory) DecodeBinary(br *io.BinReader) {
br.ReadLE(&p.Type) br.ReadLE(&p.Type)
listLen := br.ReadVarUint() listLen := br.ReadVarUint()
@ -63,12 +63,10 @@ func (p *Inventory) DecodeBinary(br *io.BinReader) error {
for i := 0; i < int(listLen); i++ { for i := 0; i < int(listLen); i++ {
br.ReadLE(&p.Hashes[i]) br.ReadLE(&p.Hashes[i])
} }
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (p *Inventory) EncodeBinary(bw *io.BinWriter) error { func (p *Inventory) EncodeBinary(bw *io.BinWriter) {
bw.WriteLE(p.Type) bw.WriteLE(p.Type)
listLen := len(p.Hashes) listLen := len(p.Hashes)
@ -76,6 +74,4 @@ func (p *Inventory) EncodeBinary(bw *io.BinWriter) error {
for i := 0; i < listLen; i++ { for i := 0; i < listLen; i++ {
bw.WriteLE(p.Hashes[i]) bw.WriteLE(p.Hashes[i])
} }
return bw.Err
} }

View file

@ -17,14 +17,14 @@ func TestInventoryEncodeDecode(t *testing.T) {
inv := NewInventory(BlockType, hashes) inv := NewInventory(BlockType, hashes)
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := inv.EncodeBinary(buf.BinWriter) inv.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
invDecode := &Inventory{} invDecode := &Inventory{}
err = invDecode.DecodeBinary(r) invDecode.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
assert.Equal(t, inv, invDecode) assert.Equal(t, inv, invDecode)
} }
@ -32,8 +32,8 @@ func TestEmptyInv(t *testing.T) {
msgInv := NewInventory(TXType, []Uint256{}) msgInv := NewInventory(TXType, []Uint256{})
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := msgInv.EncodeBinary(buf.BinWriter) msgInv.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
assert.Equal(t, []byte{byte(TXType), 0}, buf.Bytes()) assert.Equal(t, []byte{byte(TXType), 0}, buf.Bytes())
assert.Equal(t, 0, len(msgInv.Hashes)) assert.Equal(t, 0, len(msgInv.Hashes))
} }

View file

@ -14,12 +14,10 @@ type MerkleBlock struct {
Flags []byte Flags []byte
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (m *MerkleBlock) DecodeBinary(br *io.BinReader) error { func (m *MerkleBlock) DecodeBinary(br *io.BinReader) {
m.BlockBase = &core.BlockBase{} m.BlockBase = &core.BlockBase{}
if err := m.BlockBase.DecodeBinary(br); err != nil { m.BlockBase.DecodeBinary(br)
return err
}
m.TxCount = int(br.ReadVarUint()) m.TxCount = int(br.ReadVarUint())
n := br.ReadVarUint() n := br.ReadVarUint()
@ -28,10 +26,9 @@ func (m *MerkleBlock) DecodeBinary(br *io.BinReader) error {
br.ReadLE(&m.Hashes[i]) br.ReadLE(&m.Hashes[i])
} }
m.Flags = br.ReadBytes() m.Flags = br.ReadBytes()
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (m *MerkleBlock) EncodeBinary(bw *io.BinWriter) error { func (m *MerkleBlock) EncodeBinary(bw *io.BinWriter) {
return nil return
} }

View file

@ -16,12 +16,8 @@ func NewNullPayload() *NullPayload {
return &NullPayload{} return &NullPayload{}
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (p *NullPayload) DecodeBinary(r io.Reader) error { func (p *NullPayload) DecodeBinary(r *io.BinReader) {}
return nil
}
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (p *NullPayload) EncodeBinary(r io.Writer) error { func (p *NullPayload) EncodeBinary(w *io.BinWriter) {}
return nil
}

View file

@ -53,8 +53,8 @@ func NewVersion(id uint32, p uint16, ua string, h uint32, r bool) *Version {
} }
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements Serializable interface.
func (p *Version) DecodeBinary(br *io.BinReader) error { func (p *Version) DecodeBinary(br *io.BinReader) {
br.ReadLE(&p.Version) br.ReadLE(&p.Version)
br.ReadLE(&p.Services) br.ReadLE(&p.Services)
br.ReadLE(&p.Timestamp) br.ReadLE(&p.Timestamp)
@ -63,11 +63,10 @@ func (p *Version) DecodeBinary(br *io.BinReader) error {
p.UserAgent = br.ReadBytes() p.UserAgent = br.ReadBytes()
br.ReadLE(&p.StartHeight) br.ReadLE(&p.StartHeight)
br.ReadLE(&p.Relay) br.ReadLE(&p.Relay)
return br.Err
} }
// EncodeBinary implements the Payload interface. // EncodeBinary implements Serializable interface.
func (p *Version) EncodeBinary(br *io.BinWriter) error { func (p *Version) EncodeBinary(br *io.BinWriter) {
br.WriteLE(p.Version) br.WriteLE(p.Version)
br.WriteLE(p.Services) br.WriteLE(p.Services)
br.WriteLE(p.Timestamp) br.WriteLE(p.Timestamp)
@ -77,5 +76,4 @@ func (p *Version) EncodeBinary(br *io.BinWriter) error {
br.WriteBytes(p.UserAgent) br.WriteBytes(p.UserAgent)
br.WriteLE(p.StartHeight) br.WriteLE(p.StartHeight)
br.WriteLE(&p.Relay) br.WriteLE(&p.Relay)
return br.Err
} }

View file

@ -17,15 +17,15 @@ func TestVersionEncodeDecode(t *testing.T) {
version := NewVersion(id, port, useragent, height, relay) version := NewVersion(id, port, useragent, height, relay)
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
err := version.EncodeBinary(buf.BinWriter) version.EncodeBinary(buf.BinWriter)
assert.Nil(t, err) assert.Nil(t, buf.Err)
b := buf.Bytes() b := buf.Bytes()
assert.Equal(t, io.GetVarSize(version), len(b)) assert.Equal(t, io.GetVarSize(version), len(b))
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
versionDecoded := &Version{} versionDecoded := &Version{}
err = versionDecoded.DecodeBinary(r) versionDecoded.DecodeBinary(r)
assert.Nil(t, err) assert.Nil(t, r.Err)
assert.Equal(t, versionDecoded.Nonce, id) assert.Equal(t, versionDecoded.Nonce, id)
assert.Equal(t, versionDecoded.Port, port) assert.Equal(t, versionDecoded.Port, port)
assert.Equal(t, versionDecoded.UserAgent, []byte(useragent)) assert.Equal(t, versionDecoded.UserAgent, []byte(useragent))

View file

@ -130,8 +130,9 @@ func (c *Client) SendToAddress(asset util.Uint256, address string, amount util.F
if rawTx, err = CreateRawContractTransaction(txParams); err != nil { if rawTx, err = CreateRawContractTransaction(txParams); err != nil {
return nil, errors.Wrap(err, "failed to create raw transaction for `sendtoaddress`") return nil, errors.Wrap(err, "failed to create raw transaction for `sendtoaddress`")
} }
if err = rawTx.EncodeBinary(buf.BinWriter); err != nil { rawTx.EncodeBinary(buf.BinWriter)
return nil, errors.Wrap(err, "failed to encode raw transaction to binary for `sendtoaddress`") if buf.Err != nil {
return nil, errors.Wrap(buf.Err, "failed to encode raw transaction to binary for `sendtoaddress`")
} }
rawTxStr = hex.EncodeToString(buf.Bytes()) rawTxStr = hex.EncodeToString(buf.Bytes())
if resp, err = c.sendRawTransaction(rawTxStr); err != nil { if resp, err = c.sendRawTransaction(rawTxStr); err != nil {

View file

@ -296,27 +296,27 @@ func (s *Server) sendrawtransaction(reqParams Params) (interface{}, error) {
} else { } else {
r := io.NewBinReaderFromBuf(byteTx) r := io.NewBinReaderFromBuf(byteTx)
tx := &transaction.Transaction{} tx := &transaction.Transaction{}
err = tx.DecodeBinary(r) tx.DecodeBinary(r)
if err != nil { if r.Err != nil {
err = errors.Wrap(err, "transaction DecodeBinary failed") err = errors.Wrap(r.Err, "transaction DecodeBinary failed")
} } else {
relayReason := s.coreServer.RelayTxn(tx) relayReason := s.coreServer.RelayTxn(tx)
switch relayReason { switch relayReason {
case network.RelaySucceed: case network.RelaySucceed:
results = true results = true
case network.RelayAlreadyExists: case network.RelayAlreadyExists:
err = errors.New("block or transaction already exists and cannot be sent repeatedly") err = errors.New("block or transaction already exists and cannot be sent repeatedly")
case network.RelayOutOfMemory: case network.RelayOutOfMemory:
err = errors.New("the memory pool is full and no more transactions can be sent") err = errors.New("the memory pool is full and no more transactions can be sent")
case network.RelayUnableToVerify: case network.RelayUnableToVerify:
err = errors.New("the block cannot be validated") err = errors.New("the block cannot be validated")
case network.RelayInvalid: case network.RelayInvalid:
err = errors.New("block or transaction validation failed") err = errors.New("block or transaction validation failed")
case network.RelayPolicyFail: case network.RelayPolicyFail:
err = errors.New("one of the Policy filters failed") err = errors.New("one of the Policy filters failed")
default: default:
err = errors.New("unknown error") err = errors.New("unknown error")
}
} }
if err != nil { if err != nil {
resultsErr = NewInternalServerError(err.Error(), err) resultsErr = NewInternalServerError(err.Error(), err)

View file

@ -73,8 +73,9 @@ func GetInvocationScript(tx *transaction.Transaction, wif keys.WIF) ([]byte, err
buf = io.NewBufBinWriter() buf = io.NewBufBinWriter()
signature []byte signature []byte
) )
if err = tx.EncodeBinary(buf.BinWriter); err != nil { tx.EncodeBinary(buf.BinWriter)
return nil, errs.Wrap(err, "Failed to encode transaction to binary") if buf.Err != nil {
return nil, errs.Wrap(buf.Err, "Failed to encode transaction to binary")
} }
data := buf.Bytes() data := buf.Bytes()
signature, err = wif.PrivateKey.Sign(data[:(len(data) - 1)]) signature, err = wif.PrivateKey.Sign(data[:(len(data) - 1)])