mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-22 19:29:39 +00:00
io: redo Serializable to return errors in BinReader/BinWriter
Further simplifies error handling.
This commit is contained in:
parent
0bb8950f89
commit
d1a4e43c48
59 changed files with 418 additions and 605 deletions
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)])
|
||||||
|
|
Loading…
Reference in a new issue