mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-23 13:38:35 +00:00
Merge pull request #549 from nspcc-dev/serialization-and-struct-improvements
Serialization and struct improvements This set improves serialization/deserialization performance and, more importantly, simplifies memory management for some structures avoiding useless copying. It adds some percents to the 1,4M blocks import test.
This commit is contained in:
commit
36df81bf20
27 changed files with 123 additions and 101 deletions
|
@ -258,7 +258,7 @@ func (s *service) verifyBlock(b block.Block) bool {
|
||||||
|
|
||||||
func (s *service) processBlock(b block.Block) {
|
func (s *service) processBlock(b block.Block) {
|
||||||
bb := &b.(*neoBlock).Block
|
bb := &b.(*neoBlock).Block
|
||||||
bb.Script = s.getBlockWitness(bb)
|
bb.Script = *(s.getBlockWitness(bb))
|
||||||
|
|
||||||
if err := s.Chain.AddBlock(bb); err != nil {
|
if err := s.Chain.AddBlock(bb); err != nil {
|
||||||
s.log.Warnf("error on add block: %v", err)
|
s.log.Warnf("error on add block: %v", err)
|
||||||
|
|
|
@ -160,7 +160,7 @@ func (p *Payload) SetHeight(h uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinaryUnsigned writes payload to w excluding signature.
|
// EncodeBinaryUnsigned writes payload to w excluding signature.
|
||||||
func (p Payload) EncodeBinaryUnsigned(w *io.BinWriter) {
|
func (p *Payload) EncodeBinaryUnsigned(w *io.BinWriter) {
|
||||||
w.WriteLE(p.version)
|
w.WriteLE(p.version)
|
||||||
w.WriteBytes(p.prevHash[:])
|
w.WriteBytes(p.prevHash[:])
|
||||||
w.WriteLE(p.height)
|
w.WriteLE(p.height)
|
||||||
|
|
|
@ -339,10 +339,10 @@ func newMinerTx(nonce uint32) *transaction.Transaction {
|
||||||
Data: &transaction.MinerTX{
|
Data: &transaction.MinerTX{
|
||||||
Nonce: rand.Uint32(),
|
Nonce: rand.Uint32(),
|
||||||
},
|
},
|
||||||
Attributes: []*transaction.Attribute{},
|
Attributes: []transaction.Attribute{},
|
||||||
Inputs: []*transaction.Input{},
|
Inputs: []transaction.Input{},
|
||||||
Outputs: []*transaction.Output{},
|
Outputs: []transaction.Output{},
|
||||||
Scripts: []*transaction.Witness{},
|
Scripts: []transaction.Witness{},
|
||||||
Trimmed: false,
|
Trimmed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ func (u *UnspentBalance) DecodeBinary(r *io.BinReader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (u UnspentBalance) EncodeBinary(w *io.BinWriter) {
|
func (u *UnspentBalance) EncodeBinary(w *io.BinWriter) {
|
||||||
u.Tx.EncodeBinary(w)
|
u.Tx.EncodeBinary(w)
|
||||||
w.WriteLE(u.Index)
|
w.WriteLE(u.Index)
|
||||||
w.WriteLE(u.Value)
|
w.WriteLE(u.Value)
|
||||||
|
|
|
@ -43,7 +43,7 @@ type AssetState struct {
|
||||||
Precision uint8
|
Precision uint8
|
||||||
FeeMode uint8
|
FeeMode uint8
|
||||||
FeeAddress util.Uint160
|
FeeAddress util.Uint160
|
||||||
Owner *keys.PublicKey
|
Owner keys.PublicKey
|
||||||
Admin util.Uint160
|
Admin util.Uint160
|
||||||
Issuer util.Uint160
|
Issuer util.Uint160
|
||||||
Expiration uint32
|
Expiration uint32
|
||||||
|
@ -63,7 +63,6 @@ func (a *AssetState) DecodeBinary(br *io.BinReader) {
|
||||||
br.ReadLE(&a.FeeMode)
|
br.ReadLE(&a.FeeMode)
|
||||||
br.ReadBytes(a.FeeAddress[:])
|
br.ReadBytes(a.FeeAddress[:])
|
||||||
|
|
||||||
a.Owner = &keys.PublicKey{}
|
|
||||||
a.Owner.DecodeBinary(br)
|
a.Owner.DecodeBinary(br)
|
||||||
br.ReadBytes(a.Admin[:])
|
br.ReadBytes(a.Admin[:])
|
||||||
br.ReadBytes(a.Issuer[:])
|
br.ReadBytes(a.Issuer[:])
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/io"
|
"github.com/CityOfZion/neo-go/pkg/io"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -20,7 +19,6 @@ func TestEncodeDecodeAssetState(t *testing.T) {
|
||||||
Available: util.Fixed8(100),
|
Available: util.Fixed8(100),
|
||||||
Precision: 0,
|
Precision: 0,
|
||||||
FeeMode: feeMode,
|
FeeMode: feeMode,
|
||||||
Owner: &keys.PublicKey{},
|
|
||||||
Admin: randomUint160(),
|
Admin: randomUint160(),
|
||||||
Issuer: randomUint160(),
|
Issuer: randomUint160(),
|
||||||
Expiration: 10,
|
Expiration: 10,
|
||||||
|
@ -47,7 +45,6 @@ func TestPutGetAssetState(t *testing.T) {
|
||||||
Available: util.Fixed8(100),
|
Available: util.Fixed8(100),
|
||||||
Precision: 8,
|
Precision: 8,
|
||||||
FeeMode: feeMode,
|
FeeMode: feeMode,
|
||||||
Owner: &keys.PublicKey{},
|
|
||||||
Admin: randomUint160(),
|
Admin: randomUint160(),
|
||||||
Issuer: randomUint160(),
|
Issuer: randomUint160(),
|
||||||
Expiration: 10,
|
Expiration: 10,
|
||||||
|
|
|
@ -91,7 +91,6 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
|
||||||
var padding uint8
|
var padding uint8
|
||||||
br.ReadLE(&padding)
|
br.ReadLE(&padding)
|
||||||
|
|
||||||
block.Script = &transaction.Witness{}
|
|
||||||
block.Script.DecodeBinary(br)
|
block.Script.DecodeBinary(br)
|
||||||
|
|
||||||
lenTX := br.ReadVarUint()
|
lenTX := br.ReadVarUint()
|
||||||
|
@ -116,7 +115,8 @@ func (b *Block) Trim() ([]byte, error) {
|
||||||
|
|
||||||
buf.WriteVarUint(uint64(len(b.Transactions)))
|
buf.WriteVarUint(uint64(len(b.Transactions)))
|
||||||
for _, tx := range b.Transactions {
|
for _, tx := range b.Transactions {
|
||||||
tx.Hash().EncodeBinary(buf.BinWriter)
|
h := tx.Hash()
|
||||||
|
h.EncodeBinary(buf.BinWriter)
|
||||||
}
|
}
|
||||||
if buf.Err != nil {
|
if buf.Err != nil {
|
||||||
return nil, buf.Err
|
return nil, buf.Err
|
||||||
|
|
|
@ -38,7 +38,7 @@ type BlockBase struct {
|
||||||
_ uint8
|
_ uint8
|
||||||
|
|
||||||
// Script used to validate the block
|
// Script used to validate the block
|
||||||
Script *transaction.Witness `json:"script"`
|
Script transaction.Witness `json:"script"`
|
||||||
|
|
||||||
// Hash of this block, created when binary encoded (double SHA256).
|
// Hash of this block, created when binary encoded (double SHA256).
|
||||||
hash util.Uint256
|
hash util.Uint256
|
||||||
|
@ -80,7 +80,6 @@ func (b *BlockBase) DecodeBinary(br *io.BinReader) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Script = &transaction.Witness{}
|
|
||||||
b.Script.DecodeBinary(br)
|
b.Script.DecodeBinary(br)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ func newDumbBlock() *Block {
|
||||||
Index: 1,
|
Index: 1,
|
||||||
ConsensusData: 1111,
|
ConsensusData: 1111,
|
||||||
NextConsensus: hash.Hash160([]byte("a")),
|
NextConsensus: hash.Hash160([]byte("a")),
|
||||||
Script: &transaction.Witness{
|
Script: transaction.Witness{
|
||||||
VerificationScript: []byte{0x51}, // PUSH1
|
VerificationScript: []byte{0x51}, // PUSH1
|
||||||
InvocationScript: []byte{0x61}, // NOP
|
InvocationScript: []byte{0x61}, // NOP
|
||||||
},
|
},
|
||||||
|
|
|
@ -945,7 +945,7 @@ func (bc *Blockchain) References(t *transaction.Transaction) map[transaction.Inp
|
||||||
tx = nil
|
tx = nil
|
||||||
} else if tx != nil {
|
} else if tx != nil {
|
||||||
for _, in := range inputs {
|
for _, in := range inputs {
|
||||||
references[*in] = tx.Outputs[in.PrevIndex]
|
references[*in] = &tx.Outputs[in.PrevIndex]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
references = nil
|
references = nil
|
||||||
|
@ -1243,8 +1243,9 @@ func (bc *Blockchain) GetValidators(txes ...*transaction.Transaction) ([]*keys.P
|
||||||
|
|
||||||
// group inputs by the same previous hash and iterate through inputs
|
// group inputs by the same previous hash and iterate through inputs
|
||||||
group := make(map[util.Uint256][]*transaction.Input)
|
group := make(map[util.Uint256][]*transaction.Input)
|
||||||
for _, input := range tx.Inputs {
|
for i := range tx.Inputs {
|
||||||
group[input.PrevHash] = append(group[input.PrevHash], input)
|
hash := tx.Inputs[i].PrevHash
|
||||||
|
group[hash] = append(group[hash], &tx.Inputs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
for hash, inputs := range group {
|
for hash, inputs := range group {
|
||||||
|
@ -1339,7 +1340,7 @@ func processStateTX(chainState *BlockChainState, tx *transaction.StateTX) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func processEnrollmentTX(chainState *BlockChainState, tx *transaction.EnrollmentTX) error {
|
func processEnrollmentTX(chainState *BlockChainState, tx *transaction.EnrollmentTX) error {
|
||||||
validatorState, err := chainState.validators.getAndUpdate(chainState.store, tx.PublicKey)
|
validatorState, err := chainState.validators.getAndUpdate(chainState.store, &tx.PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1360,7 +1361,7 @@ func (bc *Blockchain) GetScriptHashesForVerifying(t *transaction.Transaction) ([
|
||||||
}
|
}
|
||||||
hashes := make(map[util.Uint160]bool)
|
hashes := make(map[util.Uint160]bool)
|
||||||
for _, i := range t.Inputs {
|
for _, i := range t.Inputs {
|
||||||
h := references[*i].ScriptHash
|
h := references[i].ScriptHash
|
||||||
if _, ok := hashes[h]; !ok {
|
if _, ok := hashes[h]; !ok {
|
||||||
hashes[h] = true
|
hashes[h] = true
|
||||||
}
|
}
|
||||||
|
@ -1486,7 +1487,7 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *Block
|
||||||
sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) })
|
sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) })
|
||||||
interopCtx := newInteropContext(trigger.Verification, bc, bc.store, block, t)
|
interopCtx := newInteropContext(trigger.Verification, bc, bc.store, block, t)
|
||||||
for i := 0; i < len(hashes); i++ {
|
for i := 0; i < len(hashes); i++ {
|
||||||
err := bc.verifyHashAgainstScript(hashes[i], witnesses[i], t.VerificationHash(), interopCtx)
|
err := bc.verifyHashAgainstScript(hashes[i], &witnesses[i], t.VerificationHash(), interopCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
numStr := fmt.Sprintf("witness #%d", i)
|
numStr := fmt.Sprintf("witness #%d", i)
|
||||||
return errors.Wrap(err, numStr)
|
return errors.Wrap(err, numStr)
|
||||||
|
@ -1505,7 +1506,7 @@ func (bc *Blockchain) verifyBlockWitnesses(block *Block, prevHeader *Header) err
|
||||||
hash = prevHeader.NextConsensus
|
hash = prevHeader.NextConsensus
|
||||||
}
|
}
|
||||||
interopCtx := newInteropContext(trigger.Verification, bc, bc.store, nil, nil)
|
interopCtx := newInteropContext(trigger.Verification, bc, bc.store, nil, nil)
|
||||||
return bc.verifyHashAgainstScript(hash, block.Script, block.VerificationHash(), interopCtx)
|
return bc.verifyHashAgainstScript(hash, &block.Script, block.VerificationHash(), interopCtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
|
func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
|
||||||
|
|
|
@ -20,7 +20,7 @@ func TestHeaderEncodeDecode(t *testing.T) {
|
||||||
Index: 3445,
|
Index: 3445,
|
||||||
ConsensusData: 394949,
|
ConsensusData: 394949,
|
||||||
NextConsensus: util.Uint160{},
|
NextConsensus: util.Uint160{},
|
||||||
Script: &transaction.Witness{
|
Script: transaction.Witness{
|
||||||
InvocationScript: []byte{0x10},
|
InvocationScript: []byte{0x10},
|
||||||
VerificationScript: []byte{0x11},
|
VerificationScript: []byte{0x11},
|
||||||
},
|
},
|
||||||
|
|
|
@ -55,7 +55,7 @@ func newBlock(index uint32, txs ...*transaction.Transaction) *Block {
|
||||||
vlen-(vlen-1)/3,
|
vlen-(vlen-1)/3,
|
||||||
validators,
|
validators,
|
||||||
)
|
)
|
||||||
witness := &transaction.Witness{
|
witness := transaction.Witness{
|
||||||
VerificationScript: valScript,
|
VerificationScript: valScript,
|
||||||
}
|
}
|
||||||
b := &Block{
|
b := &Block{
|
||||||
|
|
|
@ -89,8 +89,8 @@ func (ic *interopContext) txGetAttributes(v *vm.VM) error {
|
||||||
return errors.New("too many attributes")
|
return errors.New("too many attributes")
|
||||||
}
|
}
|
||||||
attrs := make([]vm.StackItem, 0, len(tx.Attributes))
|
attrs := make([]vm.StackItem, 0, len(tx.Attributes))
|
||||||
for _, attr := range tx.Attributes {
|
for i := range tx.Attributes {
|
||||||
attrs = append(attrs, vm.NewInteropItem(attr))
|
attrs = append(attrs, vm.NewInteropItem(&tx.Attributes[i]))
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(attrs)
|
v.Estack().PushVal(attrs)
|
||||||
return nil
|
return nil
|
||||||
|
@ -107,8 +107,8 @@ func (ic *interopContext) txGetInputs(v *vm.VM) error {
|
||||||
return errors.New("too many inputs")
|
return errors.New("too many inputs")
|
||||||
}
|
}
|
||||||
inputs := make([]vm.StackItem, 0, len(tx.Inputs))
|
inputs := make([]vm.StackItem, 0, len(tx.Inputs))
|
||||||
for _, input := range tx.Inputs {
|
for i := range tx.Inputs {
|
||||||
inputs = append(inputs, vm.NewInteropItem(input))
|
inputs = append(inputs, vm.NewInteropItem(&tx.Inputs[i]))
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(inputs)
|
v.Estack().PushVal(inputs)
|
||||||
return nil
|
return nil
|
||||||
|
@ -125,8 +125,8 @@ func (ic *interopContext) txGetOutputs(v *vm.VM) error {
|
||||||
return errors.New("too many outputs")
|
return errors.New("too many outputs")
|
||||||
}
|
}
|
||||||
outputs := make([]vm.StackItem, 0, len(tx.Outputs))
|
outputs := make([]vm.StackItem, 0, len(tx.Outputs))
|
||||||
for _, output := range tx.Outputs {
|
for i := range tx.Outputs {
|
||||||
outputs = append(outputs, vm.NewInteropItem(output))
|
outputs = append(outputs, vm.NewInteropItem(&tx.Outputs[i]))
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(outputs)
|
v.Estack().PushVal(outputs)
|
||||||
return nil
|
return nil
|
||||||
|
@ -146,7 +146,7 @@ func (ic *interopContext) txGetReferences(v *vm.VM) error {
|
||||||
|
|
||||||
stackrefs := make([]vm.StackItem, 0, len(refs))
|
stackrefs := make([]vm.StackItem, 0, len(refs))
|
||||||
for _, k := range tx.Inputs {
|
for _, k := range tx.Inputs {
|
||||||
tio := txInOut{*k, *refs[*k]}
|
tio := txInOut{k, *refs[k]}
|
||||||
stackrefs = append(stackrefs, vm.NewInteropItem(tio))
|
stackrefs = append(stackrefs, vm.NewInteropItem(tio))
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(stackrefs)
|
v.Estack().PushVal(stackrefs)
|
||||||
|
@ -190,8 +190,8 @@ func (ic *interopContext) txGetWitnesses(v *vm.VM) error {
|
||||||
return errors.New("too many outputs")
|
return errors.New("too many outputs")
|
||||||
}
|
}
|
||||||
scripts := make([]vm.StackItem, 0, len(tx.Scripts))
|
scripts := make([]vm.StackItem, 0, len(tx.Scripts))
|
||||||
for _, script := range tx.Scripts {
|
for i := range tx.Scripts {
|
||||||
scripts = append(scripts, vm.NewInteropItem(script))
|
scripts = append(scripts, vm.NewInteropItem(&tx.Scripts[i]))
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(scripts)
|
v.Estack().PushVal(scripts)
|
||||||
return nil
|
return nil
|
||||||
|
@ -615,7 +615,7 @@ func (ic *interopContext) assetCreate(v *vm.VM) error {
|
||||||
Name: name,
|
Name: name,
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
Precision: precision,
|
Precision: precision,
|
||||||
Owner: owner,
|
Owner: *owner,
|
||||||
Admin: admin,
|
Admin: admin,
|
||||||
Issuer: issuer,
|
Issuer: issuer,
|
||||||
Expiration: ic.bc.BlockHeight() + DefaultAssetLifetime,
|
Expiration: ic.bc.BlockHeight() + DefaultAssetLifetime,
|
||||||
|
|
|
@ -92,7 +92,7 @@ func TestTxGetInputs(t *testing.T) {
|
||||||
err := context.txGetInputs(v)
|
err := context.txGetInputs(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
value := v.Estack().Pop().Value().([]vm.StackItem)
|
value := v.Estack().Pop().Value().([]vm.StackItem)
|
||||||
require.Equal(t, tx.Inputs[0], value[0].Value().(*transaction.Input))
|
require.Equal(t, tx.Inputs[0], *value[0].Value().(*transaction.Input))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTxGetOutputs(t *testing.T) {
|
func TestTxGetOutputs(t *testing.T) {
|
||||||
|
@ -101,7 +101,7 @@ func TestTxGetOutputs(t *testing.T) {
|
||||||
err := context.txGetOutputs(v)
|
err := context.txGetOutputs(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
value := v.Estack().Pop().Value().([]vm.StackItem)
|
value := v.Estack().Pop().Value().([]vm.StackItem)
|
||||||
require.Equal(t, tx.Outputs[0], value[0].Value().(*transaction.Output))
|
require.Equal(t, tx.Outputs[0], *value[0].Value().(*transaction.Output))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTxGetType(t *testing.T) {
|
func TestTxGetType(t *testing.T) {
|
||||||
|
@ -115,16 +115,16 @@ func TestTxGetType(t *testing.T) {
|
||||||
|
|
||||||
func TestPopInputFromVM(t *testing.T) {
|
func TestPopInputFromVM(t *testing.T) {
|
||||||
v, tx, _ := createVMAndTX(t)
|
v, tx, _ := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Inputs[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0]))
|
||||||
|
|
||||||
input, err := popInputFromVM(v)
|
input, err := popInputFromVM(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tx.Inputs[0], input)
|
require.Equal(t, tx.Inputs[0], *input)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInputGetHash(t *testing.T) {
|
func TestInputGetHash(t *testing.T) {
|
||||||
v, tx, context := createVMAndTX(t)
|
v, tx, context := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Inputs[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0]))
|
||||||
|
|
||||||
err := context.inputGetHash(v)
|
err := context.inputGetHash(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -134,7 +134,7 @@ func TestInputGetHash(t *testing.T) {
|
||||||
|
|
||||||
func TestInputGetIndex(t *testing.T) {
|
func TestInputGetIndex(t *testing.T) {
|
||||||
v, tx, context := createVMAndTX(t)
|
v, tx, context := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Inputs[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0]))
|
||||||
|
|
||||||
err := context.inputGetIndex(v)
|
err := context.inputGetIndex(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -144,16 +144,16 @@ func TestInputGetIndex(t *testing.T) {
|
||||||
|
|
||||||
func TestPopOutputFromVM(t *testing.T) {
|
func TestPopOutputFromVM(t *testing.T) {
|
||||||
v, tx, _ := createVMAndTX(t)
|
v, tx, _ := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0]))
|
||||||
|
|
||||||
output, err := popOutputFromVM(v)
|
output, err := popOutputFromVM(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tx.Outputs[0], output)
|
require.Equal(t, tx.Outputs[0], *output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOutputGetAssetID(t *testing.T) {
|
func TestOutputGetAssetID(t *testing.T) {
|
||||||
v, tx, context := createVMAndTX(t)
|
v, tx, context := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0]))
|
||||||
|
|
||||||
err := context.outputGetAssetID(v)
|
err := context.outputGetAssetID(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -163,7 +163,7 @@ func TestOutputGetAssetID(t *testing.T) {
|
||||||
|
|
||||||
func TestOutputGetScriptHash(t *testing.T) {
|
func TestOutputGetScriptHash(t *testing.T) {
|
||||||
v, tx, context := createVMAndTX(t)
|
v, tx, context := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0]))
|
||||||
|
|
||||||
err := context.outputGetScriptHash(v)
|
err := context.outputGetScriptHash(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -173,7 +173,7 @@ func TestOutputGetScriptHash(t *testing.T) {
|
||||||
|
|
||||||
func TestOutputGetValue(t *testing.T) {
|
func TestOutputGetValue(t *testing.T) {
|
||||||
v, tx, context := createVMAndTX(t)
|
v, tx, context := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0]))
|
||||||
|
|
||||||
err := context.outputGetValue(v)
|
err := context.outputGetValue(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -183,7 +183,7 @@ func TestOutputGetValue(t *testing.T) {
|
||||||
|
|
||||||
func TestAttrGetData(t *testing.T) {
|
func TestAttrGetData(t *testing.T) {
|
||||||
v, tx, context := createVMAndTX(t)
|
v, tx, context := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Attributes[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Attributes[0]))
|
||||||
|
|
||||||
err := context.attrGetData(v)
|
err := context.attrGetData(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -193,7 +193,7 @@ func TestAttrGetData(t *testing.T) {
|
||||||
|
|
||||||
func TestAttrGetUsage(t *testing.T) {
|
func TestAttrGetUsage(t *testing.T) {
|
||||||
v, tx, context := createVMAndTX(t)
|
v, tx, context := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx.Attributes[0]))
|
v.Estack().PushVal(vm.NewInteropItem(&tx.Attributes[0]))
|
||||||
|
|
||||||
err := context.attrGetUsage(v)
|
err := context.attrGetUsage(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -348,7 +348,7 @@ func createVMAndAssetState(t *testing.T) (*vm.VM, *AssetState, *interopContext)
|
||||||
Precision: 1,
|
Precision: 1,
|
||||||
FeeMode: 1,
|
FeeMode: 1,
|
||||||
FeeAddress: randomUint160(),
|
FeeAddress: randomUint160(),
|
||||||
Owner: &keys.PublicKey{X: big.NewInt(1), Y: big.NewInt(1)},
|
Owner: keys.PublicKey{X: big.NewInt(1), Y: big.NewInt(1)},
|
||||||
Admin: randomUint160(),
|
Admin: randomUint160(),
|
||||||
Issuer: randomUint160(),
|
Issuer: randomUint160(),
|
||||||
Expiration: 10,
|
Expiration: 10,
|
||||||
|
@ -397,17 +397,17 @@ func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interopCont
|
||||||
tx := newMinerTX()
|
tx := newMinerTX()
|
||||||
|
|
||||||
bytes := make([]byte, 1)
|
bytes := make([]byte, 1)
|
||||||
attributes := append(tx.Attributes, &transaction.Attribute{
|
attributes := append(tx.Attributes, transaction.Attribute{
|
||||||
Usage: transaction.Description,
|
Usage: transaction.Description,
|
||||||
Data: bytes,
|
Data: bytes,
|
||||||
})
|
})
|
||||||
|
|
||||||
inputs := append(tx.Inputs, &transaction.Input{
|
inputs := append(tx.Inputs, transaction.Input{
|
||||||
PrevHash: randomUint256(),
|
PrevHash: randomUint256(),
|
||||||
PrevIndex: 1,
|
PrevIndex: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
outputs := append(tx.Outputs, &transaction.Output{
|
outputs := append(tx.Outputs, transaction.Output{
|
||||||
AssetID: randomUint256(),
|
AssetID: randomUint256(),
|
||||||
Amount: 10,
|
Amount: 10,
|
||||||
ScriptHash: randomUint160(),
|
ScriptHash: randomUint160(),
|
||||||
|
|
|
@ -288,7 +288,9 @@ func (mp MemPool) Verify(tx *transaction.Transaction) bool {
|
||||||
inputs := make([]*transaction.Input, 0)
|
inputs := make([]*transaction.Input, 0)
|
||||||
for _, item := range mp.GetVerifiedTransactions() {
|
for _, item := range mp.GetVerifiedTransactions() {
|
||||||
if tx.Hash().Equals(item.Hash()) {
|
if tx.Hash().Equals(item.Hash()) {
|
||||||
inputs = append(inputs, item.Inputs...)
|
for i := range item.Inputs {
|
||||||
|
inputs = append(inputs, &item.Inputs[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ func getAppExecResultFromStore(s storage.Store, hash util.Uint256) (*AppExecResu
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements the Serializable interface.
|
// EncodeBinary implements the Serializable interface.
|
||||||
func (ne NotificationEvent) EncodeBinary(w *io.BinWriter) {
|
func (ne *NotificationEvent) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteBytes(ne.ScriptHash[:])
|
w.WriteBytes(ne.ScriptHash[:])
|
||||||
vm.EncodeBinaryStackItem(ne.Item, w)
|
vm.EncodeBinaryStackItem(ne.Item, w)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,11 @@ import (
|
||||||
// The way to cancel the registration is: Spend the deposit on the address of the PublicKey.
|
// The way to cancel the registration is: Spend the deposit on the address of the PublicKey.
|
||||||
type EnrollmentTX struct {
|
type EnrollmentTX struct {
|
||||||
// PublicKey of the validator.
|
// PublicKey of the validator.
|
||||||
PublicKey *keys.PublicKey
|
PublicKey keys.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements Serializable interface.
|
// DecodeBinary implements Serializable interface.
|
||||||
func (tx *EnrollmentTX) DecodeBinary(r *io.BinReader) {
|
func (tx *EnrollmentTX) DecodeBinary(r *io.BinReader) {
|
||||||
tx.PublicKey = &keys.PublicKey{}
|
|
||||||
tx.PublicKey.DecodeBinary(r)
|
tx.PublicKey.DecodeBinary(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,10 @@ func NewInvocationTX(script []byte, gas util.Fixed8) *Transaction {
|
||||||
Gas: gas,
|
Gas: gas,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
},
|
},
|
||||||
Attributes: []*Attribute{},
|
Attributes: []Attribute{},
|
||||||
Inputs: []*Input{},
|
Inputs: []Input{},
|
||||||
Outputs: []*Output{},
|
Outputs: []Output{},
|
||||||
Scripts: []*Witness{},
|
Scripts: []Witness{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ type RegisterTX struct {
|
||||||
Precision uint8
|
Precision uint8
|
||||||
|
|
||||||
// Public key of the owner.
|
// Public key of the owner.
|
||||||
Owner *keys.PublicKey
|
Owner keys.PublicKey
|
||||||
|
|
||||||
Admin util.Uint160
|
Admin util.Uint160
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ func (tx *RegisterTX) DecodeBinary(br *io.BinReader) {
|
||||||
br.ReadLE(&tx.Amount)
|
br.ReadLE(&tx.Amount)
|
||||||
br.ReadLE(&tx.Precision)
|
br.ReadLE(&tx.Precision)
|
||||||
|
|
||||||
tx.Owner = &keys.PublicKey{}
|
|
||||||
tx.Owner.DecodeBinary(br)
|
tx.Owner.DecodeBinary(br)
|
||||||
|
|
||||||
br.ReadBytes(tx.Admin[:])
|
br.ReadBytes(tx.Admin[:])
|
||||||
|
|
|
@ -21,7 +21,6 @@ func TestRegisterTX(t *testing.T) {
|
||||||
Name: "this is some token I created",
|
Name: "this is some token I created",
|
||||||
Amount: util.Fixed8FromInt64(1000000),
|
Amount: util.Fixed8FromInt64(1000000),
|
||||||
Precision: 8,
|
Precision: 8,
|
||||||
Owner: &keys.PublicKey{},
|
|
||||||
Admin: someuint160,
|
Admin: someuint160,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -58,7 +57,7 @@ func TestDecodeRegisterTXFromRawString(t *testing.T) {
|
||||||
assert.Equal(t, "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]", txData.Name)
|
assert.Equal(t, "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]", txData.Name)
|
||||||
assert.Equal(t, util.Fixed8FromInt64(100000000), txData.Amount)
|
assert.Equal(t, util.Fixed8FromInt64(100000000), txData.Amount)
|
||||||
assert.Equal(t, uint8(0), txData.Precision)
|
assert.Equal(t, uint8(0), txData.Precision)
|
||||||
assert.Equal(t, &keys.PublicKey{}, txData.Owner)
|
assert.Equal(t, keys.PublicKey{}, txData.Owner)
|
||||||
assert.Equal(t, "Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt", crypto.AddressFromUint160(txData.Admin))
|
assert.Equal(t, "Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt", crypto.AddressFromUint160(txData.Admin))
|
||||||
assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().StringLE())
|
assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().StringLE())
|
||||||
|
|
||||||
|
|
|
@ -27,18 +27,18 @@ type Transaction struct {
|
||||||
Data TXer `json:"-"`
|
Data TXer `json:"-"`
|
||||||
|
|
||||||
// Transaction attributes.
|
// Transaction attributes.
|
||||||
Attributes []*Attribute `json:"attributes"`
|
Attributes []Attribute `json:"attributes"`
|
||||||
|
|
||||||
// The inputs of the transaction.
|
// The inputs of the transaction.
|
||||||
Inputs []*Input `json:"vin"`
|
Inputs []Input `json:"vin"`
|
||||||
|
|
||||||
// The outputs of the transaction.
|
// The outputs of the transaction.
|
||||||
Outputs []*Output `json:"vout"`
|
Outputs []Output `json:"vout"`
|
||||||
|
|
||||||
// The scripts that comes with this transaction.
|
// The scripts that comes with this transaction.
|
||||||
// Scripts exist out of the verification script
|
// Scripts exist out of the verification script
|
||||||
// and invocation script.
|
// and invocation script.
|
||||||
Scripts []*Witness `json:"scripts"`
|
Scripts []Witness `json:"scripts"`
|
||||||
|
|
||||||
// Hash of the transaction (double SHA256).
|
// Hash of the transaction (double SHA256).
|
||||||
hash util.Uint256
|
hash util.Uint256
|
||||||
|
@ -82,12 +82,12 @@ func (t *Transaction) VerificationHash() util.Uint256 {
|
||||||
|
|
||||||
// AddOutput adds the given output to the transaction outputs.
|
// AddOutput adds the given output to the transaction outputs.
|
||||||
func (t *Transaction) AddOutput(out *Output) {
|
func (t *Transaction) AddOutput(out *Output) {
|
||||||
t.Outputs = append(t.Outputs, out)
|
t.Outputs = append(t.Outputs, *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddInput adds the given input to the transaction inputs.
|
// AddInput adds the given input to the transaction inputs.
|
||||||
func (t *Transaction) AddInput(in *Input) {
|
func (t *Transaction) AddInput(in *Input) {
|
||||||
t.Inputs = append(t.Inputs, in)
|
t.Inputs = append(t.Inputs, *in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements Serializable interface.
|
// DecodeBinary implements Serializable interface.
|
||||||
|
@ -187,8 +187,9 @@ func (t *Transaction) createHash() error {
|
||||||
// GroupInputsByPrevHash groups all TX inputs by their previous hash.
|
// GroupInputsByPrevHash groups all TX inputs by their previous hash.
|
||||||
func (t *Transaction) GroupInputsByPrevHash() map[util.Uint256][]*Input {
|
func (t *Transaction) GroupInputsByPrevHash() map[util.Uint256][]*Input {
|
||||||
m := make(map[util.Uint256][]*Input)
|
m := make(map[util.Uint256][]*Input)
|
||||||
for _, in := range t.Inputs {
|
for i := range t.Inputs {
|
||||||
m[in.PrevHash] = append(m[in.PrevHash], in)
|
hash := t.Inputs[i].PrevHash
|
||||||
|
m[hash] = append(m[hash], &t.Inputs[i])
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
@ -196,8 +197,9 @@ func (t *Transaction) GroupInputsByPrevHash() map[util.Uint256][]*Input {
|
||||||
// GroupOutputByAssetID groups all TX outputs by their assetID.
|
// GroupOutputByAssetID groups all TX outputs by their assetID.
|
||||||
func (t Transaction) GroupOutputByAssetID() map[util.Uint256][]*Output {
|
func (t Transaction) GroupOutputByAssetID() map[util.Uint256][]*Output {
|
||||||
m := make(map[util.Uint256][]*Output)
|
m := make(map[util.Uint256][]*Output)
|
||||||
for _, out := range t.Outputs {
|
for i := range t.Outputs {
|
||||||
m[out.AssetID] = append(m[out.AssetID], out)
|
hash := t.Outputs[i].AssetID
|
||||||
|
m[hash] = append(m[hash], &t.Outputs[i])
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) {
|
||||||
Index: 0,
|
Index: 0,
|
||||||
ConsensusData: 2083236893,
|
ConsensusData: 2083236893,
|
||||||
NextConsensus: nextConsensus,
|
NextConsensus: nextConsensus,
|
||||||
Script: &transaction.Witness{
|
Script: transaction.Witness{
|
||||||
InvocationScript: []byte{},
|
InvocationScript: []byte{},
|
||||||
VerificationScript: []byte{byte(opcode.PUSHT)},
|
VerificationScript: []byte{byte(opcode.PUSHT)},
|
||||||
},
|
},
|
||||||
|
@ -56,25 +56,25 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) {
|
||||||
Data: &transaction.MinerTX{
|
Data: &transaction.MinerTX{
|
||||||
Nonce: 2083236893,
|
Nonce: 2083236893,
|
||||||
},
|
},
|
||||||
Attributes: []*transaction.Attribute{},
|
Attributes: []transaction.Attribute{},
|
||||||
Inputs: []*transaction.Input{},
|
Inputs: []transaction.Input{},
|
||||||
Outputs: []*transaction.Output{},
|
Outputs: []transaction.Output{},
|
||||||
Scripts: []*transaction.Witness{},
|
Scripts: []transaction.Witness{},
|
||||||
},
|
},
|
||||||
governingTX,
|
governingTX,
|
||||||
utilityTX,
|
utilityTX,
|
||||||
{
|
{
|
||||||
Type: transaction.IssueType,
|
Type: transaction.IssueType,
|
||||||
Data: &transaction.IssueTX{}, // no fields.
|
Data: &transaction.IssueTX{}, // no fields.
|
||||||
Inputs: []*transaction.Input{},
|
Inputs: []transaction.Input{},
|
||||||
Outputs: []*transaction.Output{
|
Outputs: []transaction.Output{
|
||||||
{
|
{
|
||||||
AssetID: governingTX.Hash(),
|
AssetID: governingTX.Hash(),
|
||||||
Amount: governingTX.Data.(*transaction.RegisterTX).Amount,
|
Amount: governingTX.Data.(*transaction.RegisterTX).Amount,
|
||||||
ScriptHash: scriptOut,
|
ScriptHash: scriptOut,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Scripts: []*transaction.Witness{
|
Scripts: []transaction.Witness{
|
||||||
{
|
{
|
||||||
InvocationScript: []byte{},
|
InvocationScript: []byte{},
|
||||||
VerificationScript: []byte{byte(opcode.PUSHT)},
|
VerificationScript: []byte{byte(opcode.PUSHT)},
|
||||||
|
@ -98,17 +98,16 @@ func governingTokenTX() *transaction.Transaction {
|
||||||
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]",
|
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]",
|
||||||
Amount: util.Fixed8FromInt64(100000000),
|
Amount: util.Fixed8FromInt64(100000000),
|
||||||
Precision: 0,
|
Precision: 0,
|
||||||
Owner: &keys.PublicKey{},
|
|
||||||
Admin: admin,
|
Admin: admin,
|
||||||
}
|
}
|
||||||
|
|
||||||
tx := &transaction.Transaction{
|
tx := &transaction.Transaction{
|
||||||
Type: transaction.RegisterType,
|
Type: transaction.RegisterType,
|
||||||
Data: registerTX,
|
Data: registerTX,
|
||||||
Attributes: []*transaction.Attribute{},
|
Attributes: []transaction.Attribute{},
|
||||||
Inputs: []*transaction.Input{},
|
Inputs: []transaction.Input{},
|
||||||
Outputs: []*transaction.Output{},
|
Outputs: []transaction.Output{},
|
||||||
Scripts: []*transaction.Witness{},
|
Scripts: []transaction.Witness{},
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx
|
return tx
|
||||||
|
@ -121,16 +120,15 @@ func utilityTokenTX() *transaction.Transaction {
|
||||||
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]",
|
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]",
|
||||||
Amount: calculateUtilityAmount(),
|
Amount: calculateUtilityAmount(),
|
||||||
Precision: 8,
|
Precision: 8,
|
||||||
Owner: &keys.PublicKey{},
|
|
||||||
Admin: admin,
|
Admin: admin,
|
||||||
}
|
}
|
||||||
tx := &transaction.Transaction{
|
tx := &transaction.Transaction{
|
||||||
Type: transaction.RegisterType,
|
Type: transaction.RegisterType,
|
||||||
Data: registerTX,
|
Data: registerTX,
|
||||||
Attributes: []*transaction.Attribute{},
|
Attributes: []transaction.Attribute{},
|
||||||
Inputs: []*transaction.Input{},
|
Inputs: []transaction.Input{},
|
||||||
Outputs: []*transaction.Output{},
|
Outputs: []transaction.Output{},
|
||||||
Scripts: []*transaction.Witness{},
|
Scripts: []transaction.Witness{},
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx
|
return tx
|
||||||
|
|
|
@ -35,7 +35,9 @@ func (w *BinWriter) WriteBE(v interface{}) {
|
||||||
w.Err = binary.Write(w.w, binary.BigEndian, v)
|
w.Err = binary.Write(w.w, binary.BigEndian, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteArray writes a slice or an array arr into w.
|
// WriteArray writes a slice or an array arr into w. Note that nil slices and
|
||||||
|
// empty slices are gonna be treated the same resulting in equal zero-length
|
||||||
|
// array encoded.
|
||||||
func (w *BinWriter) WriteArray(arr interface{}) {
|
func (w *BinWriter) WriteArray(arr interface{}) {
|
||||||
switch val := reflect.ValueOf(arr); val.Kind() {
|
switch val := reflect.ValueOf(arr); val.Kind() {
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
|
@ -49,7 +51,10 @@ func (w *BinWriter) WriteArray(arr interface{}) {
|
||||||
for i := 0; i < val.Len(); i++ {
|
for i := 0; i < val.Len(); i++ {
|
||||||
el, ok := val.Index(i).Interface().(encodable)
|
el, ok := val.Index(i).Interface().(encodable)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(typ.String() + "is not encodable")
|
el, ok = val.Index(i).Addr().Interface().(encodable)
|
||||||
|
if !ok {
|
||||||
|
panic(typ.String() + " is not encodable")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
el.EncodeBinary(w)
|
el.EncodeBinary(w)
|
||||||
|
|
|
@ -229,6 +229,18 @@ func (t *testSerializable) DecodeBinary(r *BinReader) {
|
||||||
r.ReadLE(t)
|
r.ReadLE(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testPtrSerializable uint16
|
||||||
|
|
||||||
|
// EncodeBinary implements io.Serializable interface.
|
||||||
|
func (t *testPtrSerializable) EncodeBinary(w *BinWriter) {
|
||||||
|
w.WriteLE(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeBinary implements io.Serializable interface.
|
||||||
|
func (t *testPtrSerializable) DecodeBinary(r *BinReader) {
|
||||||
|
r.ReadLE(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestBinWriter_WriteArray(t *testing.T) {
|
func TestBinWriter_WriteArray(t *testing.T) {
|
||||||
var arr [3]testSerializable
|
var arr [3]testSerializable
|
||||||
for i := range arr {
|
for i := range arr {
|
||||||
|
@ -272,6 +284,16 @@ func TestBinWriter_WriteArray(t *testing.T) {
|
||||||
w.Reset()
|
w.Reset()
|
||||||
w.Err = errors.New("error")
|
w.Err = errors.New("error")
|
||||||
require.Panics(t, func() { w.WriteArray(make(chan testSerializable)) })
|
require.Panics(t, func() { w.WriteArray(make(chan testSerializable)) })
|
||||||
|
|
||||||
|
// Ptr receiver test
|
||||||
|
var arrPtr [3]testPtrSerializable
|
||||||
|
for i := range arrPtr {
|
||||||
|
arrPtr[i] = testPtrSerializable(i)
|
||||||
|
}
|
||||||
|
w.Reset()
|
||||||
|
w.WriteArray(arr[:])
|
||||||
|
require.NoError(t, w.Err)
|
||||||
|
require.Equal(t, expected, w.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBinReader_ReadArray(t *testing.T) {
|
func TestBinReader_ReadArray(t *testing.T) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ func TestHeadersEncodeDecode(t *testing.T) {
|
||||||
BlockBase: core.BlockBase{
|
BlockBase: core.BlockBase{
|
||||||
Version: 0,
|
Version: 0,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
Script: &transaction.Witness{
|
Script: transaction.Witness{
|
||||||
InvocationScript: []byte{0x0},
|
InvocationScript: []byte{0x0},
|
||||||
VerificationScript: []byte{0x1},
|
VerificationScript: []byte{0x1},
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ func TestHeadersEncodeDecode(t *testing.T) {
|
||||||
BlockBase: core.BlockBase{
|
BlockBase: core.BlockBase{
|
||||||
Version: 0,
|
Version: 0,
|
||||||
Index: 2,
|
Index: 2,
|
||||||
Script: &transaction.Witness{
|
Script: transaction.Witness{
|
||||||
InvocationScript: []byte{0x0},
|
InvocationScript: []byte{0x0},
|
||||||
VerificationScript: []byte{0x1},
|
VerificationScript: []byte{0x1},
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@ func TestHeadersEncodeDecode(t *testing.T) {
|
||||||
BlockBase: core.BlockBase{
|
BlockBase: core.BlockBase{
|
||||||
Version: 0,
|
Version: 0,
|
||||||
Index: 3,
|
Index: 3,
|
||||||
Script: &transaction.Witness{
|
Script: transaction.Witness{
|
||||||
InvocationScript: []byte{0x0},
|
InvocationScript: []byte{0x0},
|
||||||
VerificationScript: []byte{0x1},
|
VerificationScript: []byte{0x1},
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,7 +39,7 @@ func CreateRawContractTransaction(params ContractTxParams) (*transaction.Transac
|
||||||
return nil, errs.Wrapf(err, "Failed to take script hash from address: %v", address)
|
return nil, errs.Wrapf(err, "Failed to take script hash from address: %v", address)
|
||||||
}
|
}
|
||||||
tx.Attributes = append(tx.Attributes,
|
tx.Attributes = append(tx.Attributes,
|
||||||
&transaction.Attribute{
|
transaction.Attribute{
|
||||||
Usage: transaction.Script,
|
Usage: transaction.Script,
|
||||||
Data: fromAddressHash.BytesBE(),
|
Data: fromAddressHash.BytesBE(),
|
||||||
})
|
})
|
||||||
|
@ -87,7 +87,7 @@ func SignTx(tx *transaction.Transaction, wif *keys.WIF) error {
|
||||||
return errs.Wrap(err, "failed to create invocation script")
|
return errs.Wrap(err, "failed to create invocation script")
|
||||||
}
|
}
|
||||||
witness.VerificationScript = wif.PrivateKey.PublicKey().GetVerificationScript()
|
witness.VerificationScript = wif.PrivateKey.PublicKey().GetVerificationScript()
|
||||||
tx.Scripts = append(tx.Scripts, &witness)
|
tx.Scripts = append(tx.Scripts, witness)
|
||||||
tx.Hash()
|
tx.Hash()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -117,7 +117,7 @@ func (u Uint256) MarshalJSON() ([]byte, error) {
|
||||||
func (u Uint256) CompareTo(other Uint256) int { return bytes.Compare(u[:], other[:]) }
|
func (u Uint256) CompareTo(other Uint256) int { return bytes.Compare(u[:], other[:]) }
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (u Uint256) EncodeBinary(w *io.BinWriter) {
|
func (u *Uint256) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteBytes(u[:])
|
w.WriteBytes(u[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue