From 7acf5b284179c228ce51f74a88edc631d47abfcf Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 8 May 2020 20:54:24 +0300 Subject: [PATCH] core: add SystemFee and NetworkFee to transaction closes #831 --- cli/wallet/wallet.go | 9 + pkg/consensus/consensus_test.go | 18 +- pkg/core/blockchain.go | 68 +++----- pkg/core/helper_test.go | 52 +++++- pkg/core/mempool/feer.go | 5 +- pkg/core/mempool/mem_pool.go | 24 ++- pkg/core/mempool/mem_pool_test.go | 33 ++-- pkg/core/native/native_gas.go | 24 ++- pkg/core/native/native_neo.go | 27 +-- pkg/core/native/native_nep5.go | 23 +++ pkg/core/opcode_price.go | 202 +++++++++++++++++++++++ pkg/core/transaction/transaction.go | 35 +++- pkg/core/util.go | 35 ++++ pkg/core/util_test.go | 6 +- pkg/network/helper_test.go | 10 +- pkg/rpc/client/nep5.go | 21 ++- pkg/rpc/client/rpc.go | 37 +++++ pkg/rpc/client/rpc_test.go | 130 +++++++-------- pkg/rpc/response/result/block.go | 74 +-------- pkg/rpc/response/result/tx_raw_output.go | 8 - pkg/rpc/server/server.go | 2 +- pkg/rpc/server/server_helper_test.go | 11 +- pkg/rpc/server/server_test.go | 130 +++++++++++---- pkg/rpc/server/testdata/testblocks.acc | Bin 113765 -> 114007 bytes pkg/smartcontract/context/context.go | 2 +- pkg/vm/contract_checks.go | 32 ++-- 26 files changed, 658 insertions(+), 360 deletions(-) create mode 100644 pkg/core/opcode_price.go diff --git a/cli/wallet/wallet.go b/cli/wallet/wallet.go index ae227d346..6d6779ffd 100644 --- a/cli/wallet/wallet.go +++ b/cli/wallet/wallet.go @@ -277,6 +277,10 @@ func claimGas(ctx *cli.Context) error { ScriptHash: scriptHash, }) + err = c.AddNetworkFee(tx, acc) + if err != nil { + return cli.NewExitError(err, 1) + } _ = acc.SignTx(tx) if err := c.SendRawTransaction(tx); err != nil { return cli.NewExitError(err, 1) @@ -538,6 +542,11 @@ func transferAsset(ctx *cli.Context) error { Position: 1, }) + err = c.AddNetworkFee(tx, acc) + if err != nil { + return cli.NewExitError(err, 1) + } + if outFile := ctx.String("out"); outFile != "" { priv := acc.PrivateKey() pub := priv.PublicKey() diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index eaaacaa03..0b8d3dfc3 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -25,7 +25,7 @@ func TestNewService(t *testing.T) { tx := transaction.NewContractTX() tx.ValidUntilBlock = 1 addSender(t, tx) - signTx(t, tx) + signTx(t, srv.Chain.FeePerByte(), tx) require.NoError(t, srv.Chain.PoolTx(tx)) var txx []block.Transaction @@ -45,7 +45,7 @@ func TestService_GetVerified(t *testing.T) { txs = append(txs, tx) } addSender(t, txs...) - signTx(t, txs...) + signTx(t, srv.Chain.FeePerByte(), txs...) require.NoError(t, srv.Chain.PoolTx(txs[3])) hashes := []util.Uint256{txs[0].Hash(), txs[1].Hash(), txs[2].Hash()} @@ -124,7 +124,7 @@ func TestService_getTx(t *testing.T) { tx.Nonce = 1234 tx.ValidUntilBlock = 1 addSender(t, tx) - signTx(t, tx) + signTx(t, srv.Chain.FeePerByte(), tx) h := tx.Hash() require.Equal(t, nil, srv.getTx(h)) @@ -229,10 +229,7 @@ func newTestChain(t *testing.T) *core.Blockchain { type feer struct{} -func (fs *feer) NetworkFee(*transaction.Transaction) util.Fixed8 { return util.Fixed8(0) } -func (fs *feer) IsLowPriority(util.Fixed8) bool { return false } -func (fs *feer) FeePerByte(*transaction.Transaction) util.Fixed8 { return util.Fixed8(0) } -func (fs *feer) SystemFee(*transaction.Transaction) util.Fixed8 { return util.Fixed8(0) } +func (fs *feer) IsLowPriority(util.Fixed8) bool { return false } var neoOwner = testchain.MultisigScriptHash() @@ -242,7 +239,7 @@ func addSender(t *testing.T, txs ...*transaction.Transaction) { } } -func signTx(t *testing.T, txs ...*transaction.Transaction) { +func signTx(t *testing.T, feePerByte util.Fixed8, txs ...*transaction.Transaction) { validators := make([]*keys.PublicKey, 4) privNetKeys := make([]*keys.PrivateKey, 4) for i := 0; i < 4; i++ { @@ -253,6 +250,11 @@ func signTx(t *testing.T, txs ...*transaction.Transaction) { rawScript, err := smartcontract.CreateMultiSigRedeemScript(3, validators) require.NoError(t, err) for _, tx := range txs { + size := io.GetVarSize(tx) + netFee, sizeDelta := core.CalculateNetworkFee(rawScript) + tx.NetworkFee = tx.NetworkFee.Add(netFee) + size += sizeDelta + tx.NetworkFee = tx.NetworkFee.Add(util.Fixed8(int64(size) * int64(feePerByte))) data := tx.GetSignedPart() buf := io.NewBufBinWriter() diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 18b5e90de..b59f177e3 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -466,7 +466,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error { cache := dao.NewCached(bc.dao) fee := bc.getSystemFeeAmount(block.PrevHash) for _, tx := range block.Transactions { - fee += uint32(bc.SystemFee(tx).IntegralValue()) + fee += uint32(tx.SystemFee.IntegralValue()) } if err := cache.StoreAsBlock(block, fee); err != nil { return err @@ -1117,48 +1117,10 @@ func (bc *Blockchain) references(ins []transaction.Input) ([]transaction.InOut, return references, nil } -// FeePerByte returns network fee divided by the size of the transaction. -func (bc *Blockchain) FeePerByte(t *transaction.Transaction) util.Fixed8 { - return bc.NetworkFee(t).Div(int64(io.GetVarSize(t))) -} - -// NetworkFee returns network fee. -func (bc *Blockchain) NetworkFee(t *transaction.Transaction) util.Fixed8 { - // https://github.com/neo-project/neo/blob/master-2.x/neo/Network/P2P/Payloads/ClaimTransaction.cs#L16 - if t.Type == transaction.ClaimType { - return 0 - } - - inputAmount := util.Fixed8FromInt64(0) - refs, err := bc.References(t) - if err != nil { - return inputAmount - } - for i := range refs { - if refs[i].Out.AssetID == UtilityTokenID() { - inputAmount = inputAmount.Add(refs[i].Out.Amount) - } - } - - outputAmount := util.Fixed8FromInt64(0) - for _, txOutput := range t.Outputs { - if txOutput.AssetID == UtilityTokenID() { - outputAmount = outputAmount.Add(txOutput.Amount) - } - } - - return inputAmount.Sub(outputAmount).Sub(bc.SystemFee(t)) -} - -// SystemFee returns system fee. -func (bc *Blockchain) SystemFee(t *transaction.Transaction) util.Fixed8 { - if t.Type == transaction.InvocationType { - inv := t.Data.(*transaction.InvocationTX) - if inv.Version >= 1 { - return inv.Gas - } - } - return bc.GetConfig().SystemFee.TryGetValue(t.Type) +// FeePerByte returns transaction network fee per byte. +// TODO: should be implemented as part of PolicyContract +func (bc *Blockchain) FeePerByte() util.Fixed8 { + return util.Fixed8(1000) } // IsLowPriority checks given fee for being less than configured @@ -1209,9 +1171,20 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e if t.ValidUntilBlock <= height || t.ValidUntilBlock > height+transaction.MaxValidUntilBlockIncrement { return errors.Errorf("transaction has expired. ValidUntilBlock = %d, current height = %d", t.ValidUntilBlock, height) } - if io.GetVarSize(t) > transaction.MaxTransactionSize { + balance := util.Fixed8FromInt64(bc.GetNEP5Balances(t.Sender).Trackers[bc.contracts.GAS.Hash].Balance) + need := t.SystemFee.Add(t.NetworkFee) + if balance.LessThan(need) { + return errors.Errorf("insufficient funds: balance is %v, need: %v", balance, need) + } + size := io.GetVarSize(t) + if size > transaction.MaxTransactionSize { return errors.Errorf("invalid transaction size = %d. It shoud be less then MaxTransactionSize = %d", io.GetVarSize(t), transaction.MaxTransactionSize) } + needNetworkFee := util.Fixed8(int64(size) * int64(bc.FeePerByte())) + netFee := t.NetworkFee.Sub(needNetworkFee) + if netFee < 0 { + return errors.Errorf("insufficient funds: net fee is %v, need %v", t.NetworkFee, needNetworkFee) + } if transaction.HaveDuplicateInputs(t.Inputs) { return errors.New("invalid transaction's inputs") } @@ -1392,9 +1365,8 @@ func (bc *Blockchain) PoolTx(t *transaction.Transaction) error { txSize := io.GetVarSize(t) maxFree := bc.config.MaxFreeTransactionSize if maxFree != 0 && txSize > maxFree { - netFee := bc.NetworkFee(t) - if bc.IsLowPriority(netFee) || - netFee < util.Fixed8FromFloat(bc.config.FeePerExtraByte)*util.Fixed8(txSize-maxFree) { + if bc.IsLowPriority(t.NetworkFee) || + t.NetworkFee < util.Fixed8FromFloat(bc.config.FeePerExtraByte)*util.Fixed8(txSize-maxFree) { return ErrPolicy } } @@ -1451,7 +1423,7 @@ func (bc *Blockchain) verifyResults(t *transaction.Transaction, results []*trans if len(resultsDestroy) == 1 && resultsDestroy[0].AssetID != UtilityTokenID() { return errors.New("tx destroys non-utility token") } - sysfee := bc.SystemFee(t) + sysfee := t.SystemFee if sysfee.GreaterThan(util.Fixed8(0)) { if len(resultsDestroy) == 0 { return fmt.Errorf("system requires to pay %s fee, but tx pays nothing", sysfee.String()) diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index 575f3d038..ff73ba750 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -167,10 +167,17 @@ func TestCreateBasicChain(t *testing.T) { bc := newTestChain(t) defer bc.Close() - // Move almost all NEO to one simple account. - txMoveNeo := transaction.NewContractTX() + gasHash := bc.contracts.GAS.Hash + t.Logf("native GAS hash: %v", gasHash) + + priv0 := testchain.PrivateKeyByID(0) + priv0ScriptHash := priv0.GetScriptHash() + + // Move almost all NEO and some nep5 GAS to one simple account. + txMoveNeo := newNEP5Transfer(gasHash, neoOwner, priv0ScriptHash, 1000000000) txMoveNeo.ValidUntilBlock = validUntilBlock txMoveNeo.Nonce = getNextNonce() + txMoveNeo.Sender = neoOwner // use output of issue tx from genesis block as an input genesisBlock, err := bc.GetBlock(bc.GetHeaderHash(0)) @@ -181,15 +188,10 @@ func TestCreateBasicChain(t *testing.T) { PrevHash: h, PrevIndex: 0, }) - - txMoveNeo.Sender = neoOwner - - priv0 := testchain.PrivateKeyByID(0) - priv0ScriptHash := priv0.GetScriptHash() txMoveNeo.AddOutput(&transaction.Output{ AssetID: GoverningTokenID(), Amount: neoAmount, - ScriptHash: priv0.GetScriptHash(), + ScriptHash: priv0ScriptHash, Position: 0, }) txMoveNeo.AddOutput(&transaction.Output{ @@ -198,7 +200,6 @@ func TestCreateBasicChain(t *testing.T) { ScriptHash: neoOwner, Position: 1, }) - txMoveNeo.Data = new(transaction.ContractTX) require.NoError(t, signTx(bc, txMoveNeo)) b := bc.newBlock(txMoveNeo) require.NoError(t, bc.AddBlock(b)) @@ -233,6 +234,7 @@ func TestCreateBasicChain(t *testing.T) { Position: 0, }) txNeoRound.Data = new(transaction.ContractTX) + require.NoError(t, addNetworkFee(bc, txNeoRound, acc0)) require.NoError(t, acc0.SignTx(txNeoRound)) b = bc.newBlock(txNeoRound) require.NoError(t, bc.AddBlock(b)) @@ -257,6 +259,7 @@ func TestCreateBasicChain(t *testing.T) { ScriptHash: priv0.GetScriptHash(), Position: 0, }) + require.NoError(t, addNetworkFee(bc, txClaim, acc0)) require.NoError(t, acc0.SignTx(txClaim)) b = bc.newBlock(txClaim) require.NoError(t, bc.AddBlock(b)) @@ -300,6 +303,7 @@ func TestCreateBasicChain(t *testing.T) { Position: 0, }) gasOwned -= invFee + require.NoError(t, addNetworkFee(bc, txDeploy, acc0)) require.NoError(t, acc0.SignTx(txDeploy)) b = bc.newBlock(txDeploy) require.NoError(t, bc.AddBlock(b)) @@ -313,6 +317,7 @@ func TestCreateBasicChain(t *testing.T) { txInv.Nonce = getNextNonce() txInv.ValidUntilBlock = validUntilBlock txInv.Sender = priv0ScriptHash + require.NoError(t, addNetworkFee(bc, txInv, acc0)) require.NoError(t, acc0.SignTx(txInv)) b = bc.newBlock(txInv) require.NoError(t, bc.AddBlock(b)) @@ -339,6 +344,7 @@ func TestCreateBasicChain(t *testing.T) { ScriptHash: priv0.GetScriptHash(), }) + require.NoError(t, addNetworkFee(bc, txNeo0to1, acc0)) require.NoError(t, acc0.SignTx(txNeo0to1)) b = bc.newBlock(txNeo0to1) require.NoError(t, bc.AddBlock(b)) @@ -350,24 +356,29 @@ func TestCreateBasicChain(t *testing.T) { initTx.Nonce = getNextNonce() initTx.ValidUntilBlock = validUntilBlock initTx.Sender = priv0ScriptHash + require.NoError(t, addNetworkFee(bc, initTx, acc0)) require.NoError(t, acc0.SignTx(initTx)) transferTx := newNEP5Transfer(sh, sh, priv0.GetScriptHash(), 1000) transferTx.Nonce = getNextNonce() transferTx.ValidUntilBlock = validUntilBlock transferTx.Sender = priv0ScriptHash + require.NoError(t, addNetworkFee(bc, transferTx, acc0)) require.NoError(t, acc0.SignTx(transferTx)) b = bc.newBlock(initTx, transferTx) require.NoError(t, bc.AddBlock(b)) + t.Logf("recieveRublesTx: %v", transferTx.Hash().StringBE()) transferTx = newNEP5Transfer(sh, priv0.GetScriptHash(), priv1.GetScriptHash(), 123) transferTx.Nonce = getNextNonce() transferTx.ValidUntilBlock = validUntilBlock transferTx.Sender = priv0ScriptHash + require.NoError(t, addNetworkFee(bc, transferTx, acc0)) require.NoError(t, acc0.SignTx(transferTx)) b = bc.newBlock(transferTx) require.NoError(t, bc.AddBlock(b)) + t.Logf("sendRublesTx: %v", transferTx.Hash().StringBE()) if saveChain { outStream, err := os.Create(prefix + "testblocks.acc") @@ -407,6 +418,7 @@ func TestCreateBasicChain(t *testing.T) { Position: 0, }) txNeoRound.Data = new(transaction.ContractTX) + require.NoError(t, addNetworkFee(bc, txNeoRound, acc0)) require.NoError(t, acc0.SignTx(txNeoRound)) bw := io.NewBufBinWriter() txNeoRound.EncodeBinary(bw.BinWriter) @@ -439,6 +451,11 @@ func signTx(bc *Blockchain, txs ...*transaction.Transaction) error { return errors.Wrap(err, "fail to sign tx") } for _, tx := range txs { + size := io.GetVarSize(tx) + netFee, sizeDelta := CalculateNetworkFee(rawScript) + tx.NetworkFee = tx.NetworkFee.Add(netFee) + size += sizeDelta + tx.NetworkFee = tx.NetworkFee.Add(util.Fixed8(int64(size) * int64(bc.FeePerByte()))) data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{{ InvocationScript: testchain.Sign(data), @@ -447,3 +464,20 @@ func signTx(bc *Blockchain, txs ...*transaction.Transaction) error { } return nil } + +func addNetworkFee(bc *Blockchain, tx *transaction.Transaction, sender *wallet.Account) error { + size := io.GetVarSize(tx) + netFee, sizeDelta := CalculateNetworkFee(sender.Contract.Script) + tx.NetworkFee += netFee + size += sizeDelta + for _, cosigner := range tx.Cosigners { + contract := bc.GetContractState(cosigner.Account) + if contract != nil { + netFee, sizeDelta = CalculateNetworkFee(contract.Script) + tx.NetworkFee += netFee + size += sizeDelta + } + } + tx.NetworkFee += util.Fixed8(int64(size) * int64(bc.FeePerByte())) + return nil +} diff --git a/pkg/core/mempool/feer.go b/pkg/core/mempool/feer.go index 89b63dab5..e72b9f480 100644 --- a/pkg/core/mempool/feer.go +++ b/pkg/core/mempool/feer.go @@ -1,14 +1,11 @@ package mempool import ( - "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/util" ) // Feer is an interface that abstract the implementation of the fee calculation. type Feer interface { - NetworkFee(t *transaction.Transaction) util.Fixed8 IsLowPriority(util.Fixed8) bool - FeePerByte(t *transaction.Transaction) util.Fixed8 - SystemFee(t *transaction.Transaction) util.Fixed8 + FeePerByte() util.Fixed8 } diff --git a/pkg/core/mempool/mem_pool.go b/pkg/core/mempool/mem_pool.go index 7dc38e2d4..725c2af45 100644 --- a/pkg/core/mempool/mem_pool.go +++ b/pkg/core/mempool/mem_pool.go @@ -25,11 +25,9 @@ var ( // item represents a transaction in the the Memory pool. type item struct { - txn *transaction.Transaction - timeStamp time.Time - perByteFee util.Fixed8 - netFee util.Fixed8 - isLowPrio bool + txn *transaction.Transaction + timeStamp time.Time + isLowPrio bool } // items is a slice of item. @@ -88,11 +86,11 @@ func (p *item) CompareTo(otherP *item) int { } // Fees sorted ascending. - if ret := p.perByteFee.CompareTo(otherP.perByteFee); ret != 0 { + if ret := p.txn.FeePerByte().CompareTo(otherP.txn.FeePerByte()); ret != 0 { return ret } - if ret := p.netFee.CompareTo(otherP.netFee); ret != 0 { + if ret := p.txn.NetworkFee.CompareTo(otherP.txn.NetworkFee); ret != 0 { return ret } @@ -161,12 +159,10 @@ func dropInputFromSortedSlice(slice *[]*transaction.Input, input *transaction.In // Add tries to add given transaction to the Pool. func (mp *Pool) Add(t *transaction.Transaction, fee Feer) error { var pItem = &item{ - txn: t, - timeStamp: time.Now().UTC(), - perByteFee: fee.FeePerByte(t), - netFee: fee.NetworkFee(t), + txn: t, + timeStamp: time.Now().UTC(), } - pItem.isLowPrio = fee.IsLowPriority(pItem.netFee) + pItem.isLowPrio = fee.IsLowPriority(pItem.txn.NetworkFee) mp.lock.Lock() if !mp.checkTxConflicts(t) { mp.lock.Unlock() @@ -307,7 +303,7 @@ func (mp *Pool) TryGetValue(hash util.Uint256) (*transaction.Transaction, util.F mp.lock.RLock() defer mp.lock.RUnlock() if pItem, ok := mp.verifiedMap[hash]; ok { - return pItem.txn, pItem.netFee, ok + return pItem.txn, pItem.txn.NetworkFee, ok } return nil, 0, false @@ -323,7 +319,7 @@ func (mp *Pool) GetVerifiedTransactions() []TxWithFee { for i := range mp.verifiedTxes { t[i].Tx = mp.verifiedTxes[i].txn - t[i].Fee = mp.verifiedTxes[i].netFee + t[i].Fee = mp.verifiedTxes[i].txn.NetworkFee } return t diff --git a/pkg/core/mempool/mem_pool_test.go b/pkg/core/mempool/mem_pool_test.go index bd6bd47fb..d0c3f3a9f 100644 --- a/pkg/core/mempool/mem_pool_test.go +++ b/pkg/core/mempool/mem_pool_test.go @@ -13,25 +13,15 @@ import ( type FeerStub struct { lowPriority bool - sysFee util.Fixed8 - netFee util.Fixed8 - perByteFee util.Fixed8 -} - -func (fs *FeerStub) NetworkFee(*transaction.Transaction) util.Fixed8 { - return fs.netFee + feePerByte util.Fixed8 } func (fs *FeerStub) IsLowPriority(util.Fixed8) bool { return fs.lowPriority } -func (fs *FeerStub) FeePerByte(*transaction.Transaction) util.Fixed8 { - return fs.perByteFee -} - -func (fs *FeerStub) SystemFee(*transaction.Transaction) util.Fixed8 { - return fs.sysFee +func (fs *FeerStub) FeePerByte() util.Fixed8 { + return fs.feePerByte } func testMemPoolAddRemoveWithFeer(t *testing.T, fs Feer) { @@ -235,18 +225,27 @@ func TestOverCapacity(t *testing.T) { require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) // Fees are also prioritized. - fs.netFee = util.Fixed8FromFloat(0.0001) for i := 0; i < mempoolSize-1; i++ { tx := transaction.NewContractTX() + tx.Attributes = append(tx.Attributes, transaction.Attribute{ + Usage: transaction.Hash1, + Data: util.Uint256{1, 2, 3, 4}.BytesBE(), + }) + tx.NetworkFee = util.Fixed8FromFloat(0.0001) tx.Nonce = txcnt txcnt++ + // size is 84, networkFee is 0.0001 => feePerByte is 0.00000119 require.NoError(t, mp.Add(tx, fs)) require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) } // Less prioritized txes are not allowed anymore. - fs.netFee = util.Fixed8FromFloat(0.00001) tx := transaction.NewContractTX() + tx.Attributes = append(tx.Attributes, transaction.Attribute{ + Usage: transaction.Hash1, + Data: util.Uint256{1, 2, 3, 4}.BytesBE(), + }) + tx.NetworkFee = util.Fixed8FromFloat(0.00001) tx.Nonce = txcnt txcnt++ require.Error(t, mp.Add(tx, fs)) @@ -257,10 +256,12 @@ func TestOverCapacity(t *testing.T) { require.True(t, mp.ContainsKey(claim.Hash())) // Low net fee, but higher per-byte fee is still a better combination. - fs.perByteFee = util.Fixed8FromFloat(0.001) tx = transaction.NewContractTX() tx.Nonce = txcnt + tx.NetworkFee = util.Fixed8FromFloat(0.00007) txcnt++ + // size is 51 (no attributes), networkFee is 0.00007 (<0.0001) + // => feePerByte is 0.00000137 (>0.00000119) require.NoError(t, mp.Add(tx, fs)) require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) diff --git a/pkg/core/native/native_gas.go b/pkg/core/native/native_gas.go index 1c5351ef0..8706f1ea1 100644 --- a/pkg/core/native/native_gas.go +++ b/pkg/core/native/native_gas.go @@ -2,6 +2,7 @@ package native import ( "errors" + "fmt" "math/big" "github.com/nspcc-dev/neo-go/pkg/core/interop" @@ -80,15 +81,20 @@ func (g *GAS) Initialize(ic *interop.Context) error { // OnPersist implements Contract interface. func (g *GAS) OnPersist(ic *interop.Context) error { - //for _ ,tx := range ic.block.Transactions { - // g.burn(ic, tx.Sender, tx.SystemFee + tx.NetworkFee) - //} - //validators := g.NEO.getNextBlockValidators(ic) - //var netFee util.Fixed8 - //for _, tx := range ic.block.Transactions { - // netFee += tx.NetworkFee - //} - //g.mint(ic, , netFee) + for _, tx := range ic.Block.Transactions { + absAmount := big.NewInt(int64(tx.SystemFee + tx.NetworkFee)) + g.burn(ic, tx.Sender, absAmount) + } + validators, err := g.NEO.GetValidatorsInternal(ic.Chain, ic.DAO) + if err != nil { + return fmt.Errorf("cannot get block validators: %v", err) + } + primary := validators[ic.Block.ConsensusData.PrimaryIndex].GetScriptHash() + var netFee util.Fixed8 + for _, tx := range ic.Block.Transactions { + netFee += tx.NetworkFee + } + g.mint(ic, primary, big.NewInt(int64(netFee))) return nil } diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index e4bcc4246..67bc5b832 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -251,7 +251,11 @@ func (n *NEO) vote(ic *interop.Context, args []vm.StackItem) vm.StackItem { // VoteInternal votes from account h for validarors specified in pubs. func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pubs keys.PublicKeys) error { - ok, err := runtime.CheckHashedWitness(ic, neoScriptHash{hash: n.Hash}, h) + ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{ + callingScriptHash: util.Uint160{}, + entryScriptHash: n.Hash, + currentScriptHash: n.Hash, + }, h) if err != nil { return err } else if !ok { @@ -479,24 +483,3 @@ func toPublicKey(s vm.StackItem) *keys.PublicKey { } return pub } - -// scriptHash is an auxiliary structure which implements ScriptHashGetter -// interface over NEO native contract and is used for runtime.CheckHashedWitness -type neoScriptHash struct { - hash util.Uint160 -} - -// GetCallingScriptHash implements ScriptHashGetter interface -func (s neoScriptHash) GetCallingScriptHash() util.Uint160 { - return util.Uint160{} -} - -// GetEntryScriptHash implements ScriptHashGetter interface -func (s neoScriptHash) GetEntryScriptHash() util.Uint160 { - return s.hash -} - -// GetCurrentScriptHash implements ScriptHashGetter interface -func (s neoScriptHash) GetCurrentScriptHash() util.Uint160 { - return s.hash -} diff --git a/pkg/core/native/native_nep5.go b/pkg/core/native/native_nep5.go index b599313da..190579616 100644 --- a/pkg/core/native/native_nep5.go +++ b/pkg/core/native/native_nep5.go @@ -268,3 +268,26 @@ func toUint160(s vm.StackItem) util.Uint160 { } return u } + +// scriptHash is an auxiliary structure which implements ScriptHashGetter +// interface over NEP5 native contract and is used for runtime.CheckHashedWitness +type nep5ScriptHash struct { + callingScriptHash util.Uint160 + entryScriptHash util.Uint160 + currentScriptHash util.Uint160 +} + +// GetCallingScriptHash implements ScriptHashGetter interface +func (s nep5ScriptHash) GetCallingScriptHash() util.Uint160 { + return s.callingScriptHash +} + +// GetEntryScriptHash implements ScriptHashGetter interface +func (s nep5ScriptHash) GetEntryScriptHash() util.Uint160 { + return s.entryScriptHash +} + +// GetCurrentScriptHash implements ScriptHashGetter interface +func (s nep5ScriptHash) GetCurrentScriptHash() util.Uint160 { + return s.currentScriptHash +} diff --git a/pkg/core/opcode_price.go b/pkg/core/opcode_price.go new file mode 100644 index 000000000..06302c051 --- /dev/null +++ b/pkg/core/opcode_price.go @@ -0,0 +1,202 @@ +package core + +import ( + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm/opcode" +) + +// opcodePrice returns the deployment prices of specified opcodes +func opcodePrice(opcodes ...opcode.Opcode) util.Fixed8 { + var result util.Fixed8 + for _, op := range opcodes { + result += util.Fixed8(prices[op]) + } + return result +} + +var prices = map[opcode.Opcode]int{ + opcode.PUSHINT8: 30, + opcode.PUSHINT32: 30, + opcode.PUSHINT64: 30, + opcode.PUSHINT16: 30, + opcode.PUSHINT128: 120, + opcode.PUSHINT256: 120, + opcode.PUSHA: 120, + opcode.PUSHNULL: 30, + opcode.PUSHDATA1: 180, + opcode.PUSHDATA2: 13000, + opcode.PUSHDATA4: 110000, + opcode.PUSHM1: 30, + opcode.PUSH0: 30, + opcode.PUSH1: 30, + opcode.PUSH2: 30, + opcode.PUSH3: 30, + opcode.PUSH4: 30, + opcode.PUSH5: 30, + opcode.PUSH6: 30, + opcode.PUSH7: 30, + opcode.PUSH8: 30, + opcode.PUSH9: 30, + opcode.PUSH10: 30, + opcode.PUSH11: 30, + opcode.PUSH12: 30, + opcode.PUSH13: 30, + opcode.PUSH14: 30, + opcode.PUSH15: 30, + opcode.PUSH16: 30, + opcode.NOP: 30, + opcode.JMP: 70, + opcode.JMPL: 70, + opcode.JMPIF: 70, + opcode.JMPIFL: 70, + opcode.JMPIFNOT: 70, + opcode.JMPIFNOTL: 70, + opcode.JMPEQ: 70, + opcode.JMPEQL: 70, + opcode.JMPNE: 70, + opcode.JMPNEL: 70, + opcode.JMPGT: 70, + opcode.JMPGTL: 70, + opcode.JMPGE: 70, + opcode.JMPGEL: 70, + opcode.JMPLT: 70, + opcode.JMPLTL: 70, + opcode.JMPLE: 70, + opcode.JMPLEL: 70, + opcode.CALL: 22000, + opcode.CALLL: 22000, + opcode.CALLA: 22000, + opcode.ABORT: 30, + opcode.ASSERT: 30, + opcode.THROW: 22000, + //opcode.TRY: 100, + //opcode.TRY_L: 100, + //opcode.ENDTRY: 100, + //opcode.ENDTRY_L: 100, + //opcode.ENDFINALLY: 100, + opcode.RET: 0, + opcode.SYSCALL: 0, + opcode.DEPTH: 60, + opcode.DROP: 60, + opcode.NIP: 60, + opcode.XDROP: 400, + opcode.CLEAR: 400, + opcode.DUP: 60, + opcode.OVER: 60, + opcode.PICK: 60, + opcode.TUCK: 60, + opcode.SWAP: 60, + opcode.ROT: 60, + opcode.ROLL: 400, + opcode.REVERSE3: 60, + opcode.REVERSE4: 60, + opcode.REVERSEN: 400, + opcode.INITSSLOT: 400, + opcode.INITSLOT: 800, + opcode.LDSFLD0: 60, + opcode.LDSFLD1: 60, + opcode.LDSFLD2: 60, + opcode.LDSFLD3: 60, + opcode.LDSFLD4: 60, + opcode.LDSFLD5: 60, + opcode.LDSFLD6: 60, + opcode.LDSFLD: 60, + opcode.STSFLD0: 60, + opcode.STSFLD1: 60, + opcode.STSFLD2: 60, + opcode.STSFLD3: 60, + opcode.STSFLD4: 60, + opcode.STSFLD5: 60, + opcode.STSFLD6: 60, + opcode.STSFLD: 60, + opcode.LDLOC0: 60, + opcode.LDLOC1: 60, + opcode.LDLOC2: 60, + opcode.LDLOC3: 60, + opcode.LDLOC4: 60, + opcode.LDLOC5: 60, + opcode.LDLOC6: 60, + opcode.LDLOC: 60, + opcode.STLOC0: 60, + opcode.STLOC1: 60, + opcode.STLOC2: 60, + opcode.STLOC3: 60, + opcode.STLOC4: 60, + opcode.STLOC5: 60, + opcode.STLOC6: 60, + opcode.STLOC: 60, + opcode.LDARG0: 60, + opcode.LDARG1: 60, + opcode.LDARG2: 60, + opcode.LDARG3: 60, + opcode.LDARG4: 60, + opcode.LDARG5: 60, + opcode.LDARG6: 60, + opcode.LDARG: 60, + opcode.STARG0: 60, + opcode.STARG1: 60, + opcode.STARG2: 60, + opcode.STARG3: 60, + opcode.STARG4: 60, + opcode.STARG5: 60, + opcode.STARG6: 60, + opcode.STARG: 60, + opcode.NEWBUFFER: 80000, + opcode.MEMCPY: 80000, + opcode.CAT: 80000, + opcode.SUBSTR: 80000, + opcode.LEFT: 80000, + opcode.RIGHT: 80000, + opcode.INVERT: 100, + opcode.AND: 200, + opcode.OR: 200, + opcode.XOR: 200, + opcode.EQUAL: 200, + opcode.NOTEQUAL: 200, + opcode.SIGN: 100, + opcode.ABS: 100, + opcode.NEGATE: 100, + opcode.INC: 100, + opcode.DEC: 100, + opcode.ADD: 200, + opcode.SUB: 200, + opcode.MUL: 300, + opcode.DIV: 300, + opcode.MOD: 300, + opcode.SHL: 300, + opcode.SHR: 300, + opcode.NOT: 100, + opcode.BOOLAND: 200, + opcode.BOOLOR: 200, + opcode.NZ: 100, + opcode.NUMEQUAL: 200, + opcode.NUMNOTEQUAL: 200, + opcode.LT: 200, + opcode.LTE: 200, + opcode.GT: 200, + opcode.GTE: 200, + opcode.MIN: 200, + opcode.MAX: 200, + opcode.WITHIN: 200, + opcode.PACK: 7000, + opcode.UNPACK: 7000, + opcode.NEWARRAY0: 400, + opcode.NEWARRAY: 15000, + opcode.NEWARRAYT: 15000, + opcode.NEWSTRUCT0: 400, + opcode.NEWSTRUCT: 15000, + opcode.NEWMAP: 200, + opcode.SIZE: 150, + opcode.HASKEY: 270000, + opcode.KEYS: 500, + opcode.VALUES: 7000, + opcode.PICKITEM: 270000, + opcode.APPEND: 15000, + opcode.SETITEM: 270000, + opcode.REVERSEITEMS: 500, + opcode.REMOVE: 500, + opcode.CLEARITEMS: 400, + opcode.ISNULL: 60, + opcode.ISTYPE: 60, + opcode.CONVERT: 80000, +} diff --git a/pkg/core/transaction/transaction.go b/pkg/core/transaction/transaction.go index e2e399c2a..6099ddaa2 100644 --- a/pkg/core/transaction/transaction.go +++ b/pkg/core/transaction/transaction.go @@ -38,6 +38,12 @@ type Transaction struct { // Address signed the transaction. Sender util.Uint160 + // Fee to be burned. + SystemFee util.Fixed8 + + // Fee to be distributed to consensus nodes. + NetworkFee util.Fixed8 + // Maximum blockchain height exceeding which // transaction should fail verification. ValidUntilBlock uint32 @@ -119,7 +125,20 @@ func (t *Transaction) DecodeBinary(br *io.BinReader) { t.Version = uint8(br.ReadB()) t.Nonce = br.ReadU32LE() t.Sender.DecodeBinary(br) - + t.SystemFee.DecodeBinary(br) + if t.SystemFee < 0 { + br.Err = errors.New("negative system fee") + return + } + t.NetworkFee.DecodeBinary(br) + if t.NetworkFee < 0 { + br.Err = errors.New("negative network fee") + return + } + if t.NetworkFee+t.SystemFee < t.SystemFee { + br.Err = errors.New("too big fees: int 64 overflow") + return + } t.ValidUntilBlock = br.ReadU32LE() t.decodeData(br) @@ -192,6 +211,8 @@ func (t *Transaction) encodeHashableFields(bw *io.BinWriter) { bw.WriteB(byte(t.Version)) bw.WriteU32LE(t.Nonce) t.Sender.EncodeBinary(bw) + t.SystemFee.EncodeBinary(bw) + t.NetworkFee.EncodeBinary(bw) bw.WriteU32LE(t.ValidUntilBlock) // Underlying TXer. @@ -268,6 +289,12 @@ func NewTransactionFromBytes(b []byte) (*Transaction, error) { return tx, nil } +// FeePerByte returns NetworkFee of the transaction divided by +// its size +func (t *Transaction) FeePerByte() util.Fixed8 { + return util.Fixed8(int64(t.NetworkFee) / int64(io.GetVarSize(t))) +} + // transactionJSON is a wrapper for Transaction and // used for correct marhalling of transaction.Data type transactionJSON struct { @@ -277,6 +304,8 @@ type transactionJSON struct { Version uint8 `json:"version"` Nonce uint32 `json:"nonce"` Sender string `json:"sender"` + SystemFee util.Fixed8 `json:"sys_fee"` + NetworkFee util.Fixed8 `json:"net_fee"` ValidUntilBlock uint32 `json:"valid_until_block"` Attributes []Attribute `json:"attributes"` Cosigners []Cosigner `json:"cosigners"` @@ -305,6 +334,8 @@ func (t *Transaction) MarshalJSON() ([]byte, error) { Inputs: t.Inputs, Outputs: t.Outputs, Scripts: t.Scripts, + SystemFee: t.SystemFee, + NetworkFee: t.NetworkFee, } switch t.Type { case ClaimType: @@ -341,6 +372,8 @@ func (t *Transaction) UnmarshalJSON(data []byte) error { t.Inputs = tx.Inputs t.Outputs = tx.Outputs t.Scripts = tx.Scripts + t.SystemFee = tx.SystemFee + t.NetworkFee = tx.NetworkFee sender, err := address.StringToUint160(tx.Sender) if err != nil { return errors.New("cannot unmarshal tx: bad sender") diff --git a/pkg/core/util.go b/pkg/core/util.go index 1c998d724..643e101e2 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -11,6 +11,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" ) @@ -24,6 +25,10 @@ var ( // utility (GAS) token. It's a part of the genesis block. It's mostly // useful for its hash that represents GAS asset ID. utilityTokenTX transaction.Transaction + + // ecdsaVerifyInteropPrice returns the price of Neo.Crypto.ECDsaVerify + // syscall to calculate NetworkFee for transaction + ecdsaVerifyInteropPrice = util.Fixed8(100000) ) // createGenesisBlock creates a genesis block based on the given configuration. @@ -191,3 +196,33 @@ func headerSliceReverse(dest []*block.Header) { dest[i], dest[j] = dest[j], dest[i] } } + +// CalculateNetworkFee returns network fee for transaction +func CalculateNetworkFee(script []byte) (util.Fixed8, int) { + var ( + netFee util.Fixed8 + size int + ) + if vm.IsSignatureContract(script) { + size += 67 + io.GetVarSize(script) + netFee = netFee.Add(opcodePrice(opcode.PUSHDATA1, opcode.PUSHNULL).Add(ecdsaVerifyInteropPrice)) + } else if n, pubs, ok := vm.ParseMultiSigContract(script); ok { + m := len(pubs) + sizeInv := 66 * m + size += io.GetVarSize(sizeInv) + sizeInv + io.GetVarSize(script) + netFee = netFee.Add(calculateMultisigFee(m)).Add(calculateMultisigFee(n)) + netFee = netFee.Add(opcodePrice(opcode.PUSHNULL)).Add(util.Fixed8(int64(ecdsaVerifyInteropPrice) * int64(n))) + } else { + // We can support more contract types in the future. + } + return netFee, size +} + +func calculateMultisigFee(n int) util.Fixed8 { + result := util.Fixed8(int64(opcodePrice(opcode.PUSHDATA1)) * int64(n)) + bw := io.NewBufBinWriter() + emit.Int(bw.BinWriter, int64(n)) + // it's a hack because prices of small PUSH* opcodes are equal + result = result.Add(opcodePrice(opcode.Opcode(bw.Bytes()[0]))) + return result +} diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index 90d8dbbe7..090bfb8ac 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -20,7 +20,7 @@ func TestGenesisBlockMainNet(t *testing.T) { // have been changed. Consequently, hash of the genesis block has been changed. // Update expected genesis block hash for better times. // Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf" - expect := "56bb42c251ea2b216c5ee8306e94fe040613bc626a3813aa32fe07e7607b3a1a" + expect := "1d4156d233220b893797a684fbb827bb2163b5042edd10653bbc1b2769adbb8d" assert.Equal(t, expect, block.Hash().StringLE()) } @@ -47,7 +47,7 @@ func TestUtilityTokenTX(t *testing.T) { //TODO: After we added Nonce field to transaction.Transaction, UtilityTockenTx hash // has been changed. Update it for better times. // Old hash is "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7" - expect := "8ef63ccd6f4ea20a93e7f4e84b2d43f778077612b241d617e42e1750cca4f2c5" + expect := "f882fb865bab84b99623f21eedd902286af7da8d8a4609d7acefce04c851dc1c" assert.Equal(t, expect, UtilityTokenID().StringLE()) } @@ -55,6 +55,6 @@ func TestGoverningTokenTX(t *testing.T) { //TODO: After we added Nonce field to transaction.Transaction, GoveringTockenTx hash // has been changed. Update it for better times. // Old hash is "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" - expect := "7dc12f8835b085d468ddbab3f7152c0e2f5679b5815b2028685abb4608e7b7dc" + expect := "1a5e0e3eac2abced7de9ee2de0820a5c85e63756fcdfc29b82fead86a7c07c78" assert.Equal(t, expect, GoverningTokenID().StringLE()) } diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index 6ef6487aa..db2452eda 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -38,15 +38,7 @@ func (chain testChain) References(t *transaction.Transaction) ([]transaction.InO panic("TODO") } -func (chain testChain) FeePerByte(t *transaction.Transaction) util.Fixed8 { - panic("TODO") -} - -func (chain testChain) SystemFee(t *transaction.Transaction) util.Fixed8 { - panic("TODO") -} - -func (chain testChain) NetworkFee(t *transaction.Transaction) util.Fixed8 { +func (chain testChain) FeePerByte() util.Fixed8 { panic("TODO") } diff --git a/pkg/rpc/client/nep5.go b/pkg/rpc/client/nep5.go index 88ccc4671..1b5eb1b95 100644 --- a/pkg/rpc/client/nep5.go +++ b/pkg/rpc/client/nep5.go @@ -1,6 +1,7 @@ package client import ( + "encoding/hex" "errors" "fmt" @@ -107,9 +108,22 @@ func (c *Client) TransferNEP5(acc *wallet.Account, to util.Uint160, token *walle emit.AppCallWithOperationAndArgs(w.BinWriter, token.Hash, "transfer", from, to, amount) emit.Opcode(w.BinWriter, opcode.ASSERT) - tx := transaction.NewInvocationTX(w.Bytes(), gas) + script := w.Bytes() + tx := transaction.NewInvocationTX(script, gas) tx.Sender = from + result, err := c.InvokeScript(hex.EncodeToString(script)) + if err != nil { + return util.Uint256{}, fmt.Errorf("can't add system fee to transaction: %v", err) + } + gasConsumed, err := util.Fixed8FromString(result.GasConsumed) + if err != nil { + return util.Uint256{}, fmt.Errorf("can't add system fee to transaction: %v", err) + } + if gasConsumed > 0 { + tx.SystemFee = gasConsumed + } + tx.ValidUntilBlock, err = c.CalculateValidUntilBlock() if err != nil { return util.Uint256{}, fmt.Errorf("can't calculate validUntilBlock: %v", err) @@ -119,6 +133,11 @@ func (c *Client) TransferNEP5(acc *wallet.Account, to util.Uint160, token *walle return util.Uint256{}, fmt.Errorf("can't add GAS to transaction: %v", err) } + err = c.AddNetworkFee(tx, acc) + if err != nil { + return util.Uint256{}, fmt.Errorf("can't add network fee to transaction: %v", err) + } + if err := acc.SignTx(tx); err != nil { return util.Uint256{}, fmt.Errorf("can't sign tx: %v", err) } diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index 3e53db23d..e0b8326bd 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -511,6 +511,8 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys var err error tx := transaction.NewInvocationTX(script, sysfee) + tx.SystemFee = sysfee + validUntilBlock, err := c.CalculateValidUntilBlock() if err != nil { return txHash, errors.Wrap(err, "failed to add validUntilBlock to transaction") @@ -531,6 +533,11 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys } } + err = c.AddNetworkFee(tx, acc) + if err != nil { + return txHash, errors.Wrapf(err, "failed to add network fee") + } + if err = acc.SignTx(tx); err != nil { return txHash, errors.Wrap(err, "failed to sign tx") } @@ -588,3 +595,33 @@ func (c *Client) CalculateValidUntilBlock() (uint32, error) { } return blockCount + validatorsCount, nil } + +// AddNetworkFee adds network fee for each witness script to transaction. +func (c *Client) AddNetworkFee(tx *transaction.Transaction, acc *wallet.Account) error { + size := io.GetVarSize(tx) + if acc.Contract != nil { + netFee, sizeDelta := core.CalculateNetworkFee(acc.Contract.Script) + tx.NetworkFee += netFee + size += sizeDelta + } + for _, cosigner := range tx.Cosigners { + contract, err := c.GetContractState(cosigner.Account) + if err != nil { + return err + } + if contract == nil { + continue + } + netFee, sizeDelta := core.CalculateNetworkFee(contract.Script) + tx.NetworkFee += netFee + size += sizeDelta + } + tx.NetworkFee += util.Fixed8(int64(size) * int64(c.GetFeePerByte())) + return nil +} + +// GetFeePerByte returns transaction network fee per byte +func (c *Client) GetFeePerByte() util.Fixed8 { + // TODO: make it a part of policy contract + return util.Fixed8(1000) +} diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index 8ceda6640..3bcf13f7a 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -40,7 +40,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ invoke: func(c *Client) (interface{}, error) { return c.GetAccountState("") }, - serverResponse: `{"jsonrpc":"2.0","id": 1,"result":{"version":0,"script_hash":"0x1179716da2e9523d153a35fb3ad10c561b1e5b1a","frozen":false,"votes":[],"balances":[{"asset":"0x7dc12f8835b085d468ddbab3f7152c0e2f5679b5815b2028685abb4608e7b7dc","value":"94"}]}}`, + serverResponse: `{"jsonrpc":"2.0","id": 1,"result":{"version":0,"script_hash":"0x1179716da2e9523d153a35fb3ad10c561b1e5b1a","frozen":false,"votes":[],"balances":[{"asset":"0x1a5e0e3eac2abced7de9ee2de0820a5c85e63756fcdfc29b82fead86a7c07c78","value":"94"}]}}`, result: func(c *Client) interface{} { scriptHash, err := util.Uint160DecodeStringLE("1179716da2e9523d153a35fb3ad10c561b1e5b1a") if err != nil { @@ -98,7 +98,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ invoke: func(c *Client) (interface{}, error) { return c.GetAssetState(util.Uint256{}) }, - serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":"0x7dc12f8835b085d468ddbab3f7152c0e2f5679b5815b2028685abb4608e7b7dc","type":0,"name":"NEO","amount":"100000000","available":"100000000","precision":0,"owner":"00","admin":"Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt","issuer":"AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM","expiration":4000000,"is_frozen":false}}`, + serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":"0x1a5e0e3eac2abced7de9ee2de0820a5c85e63756fcdfc29b82fead86a7c07c78","type":0,"name":"NEO","amount":"100000000","available":"100000000","precision":0,"owner":"00","admin":"Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt","issuer":"AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM","expiration":4000000,"is_frozen":false}}`, result: func(c *Client) interface{} { return &result.AssetState{ ID: core.GoverningTokenID(), @@ -138,17 +138,17 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ invoke: func(c *Client) (interface{}, error) { return c.GetBlockByIndex(202) }, - serverResponse: `{"id":1,"jsonrpc":"2.0","result":"0000000039f06b13aa6ee24d37db9b7868533b7988a6fb1e59c3fa6677dab7fd1f51326405f4fa24f061ffa04ab3127994530ee04c5e578a7b8109133dd142b6a31192cd9debaa5e00000000ca000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c404617b6788538326383015c44ffddd4a05a4e200b65a26fc84234ae8b1e28ef27b7f139dc498c58071193d530ba83081701290eba8f7108397499f5556c16e3780c402131f2bdcc494c73a379e86c46f9e9fe9899a05b23928926b1eaaf816928e160fe971b82263aa1e7efa5f7e46bf99de735fc4fc5aeb81edfdc6a9b2e9fcfa1000c408cbae1582bb9d82de9ff030b8c729737f2157844c0ca29edcdbfed1dd5e2473e0061f0dc29412477417e2c1f7c55443f11b9bd6e0d0856d1ec00240be1b9b9a70c4034d1055531cf0522ac7e5dcd817cf3cd86997ae38da806dc789b1f16eb0005f00b9bc29f7372bb43a8fed040c6763b162c8a0d8e2d0b2d7476e22e0b2b77601094130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb0200570400000000000080000300000075a94799633ed955dd85a8af314a5b435ab51903b0040000000001f6c31d4dd9edf7aea24168885ae82dc574d25e35a9b9b3063f3ea44226a3081f000001dcb7e70846bb5a6828205b81b579562f0e2c15f7b3badd68d485b035882fc17d00184a27db86230075a94799633ed955dd85a8af314a5b435ab5190301420c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"}`, + serverResponse: `{"id":1,"jsonrpc":"2.0","result":"00000000ef9039404248180eb395d8ff59f985286b6852a68275a487e473114c4240b5938dccbfab32ee60f8b0d16144f258cc30d4f6795522fbd60109e2ed8d1423e9b810cdba5e00000000ca000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c403620ef8f02d7884c553fb6c54d2fe717cfddd9450886c5fc88a669a29a82fa1a7c715076996567a5a56747f20f10d7e4db071d73b306ccbf17f9a916fcfa1d020c4099e27d87bbb3fb4ce1c77dca85cf3eac46c9c3de87d8022ef7ad2b0a2bb980339293849cf85e5a0a5615ea7bc5bb0a7f28e31f278dc19d628f64c49b888df4c60c40616eefc9286843c2f3f2cf1815988356e409b3f10ffaf60b3468dc0a92dd929cbc8d5da74052c303e7474412f6beaddd551e9056c4e7a5fccdc06107e48f3fe10c40fd2d25d4156e969345c0522669b509e5ced70e4265066eadaf85eea3919d5ded525f8f52d6f0dfa0186c964dd0302fca5bc2dc0540b4ed21085be478c312399694130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb02005704000000000000800003000000316e851039019d39dfc2c37d6c3fee19fd58098700000000000000000000000000000000b004000000000170f3b507ea9eae15ebb7f10195c1239bbaa12ca996ff070e4a8501131045e033000001787cc0a786adfe829bc2dffc5637e6855c0a82e02deee97dedbc2aac3e0e5e1a00184a27db862300316e851039019d39dfc2c37d6c3fee19fd58098701420c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"}`, result: func(c *Client) interface{} { return &block.Block{} }, check: func(t *testing.T, c *Client, result interface{}) { res, ok := result.(*block.Block) require.True(t, ok) assert.Equal(t, uint32(0), res.Version) - assert.Equal(t, "75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45", res.Hash().StringLE()) - assert.Equal(t, "6432511ffdb7da7766fac3591efba688793b5368789bdb374de26eaa136bf039", res.PrevHash.StringLE()) - assert.Equal(t, "cd9211a3b642d13d1309817b8a575e4ce00e53947912b34aa0ff61f024faf405", res.MerkleRoot.StringLE()) + assert.Equal(t, "cbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86", res.Hash().StringLE()) + assert.Equal(t, "93b540424c1173e487a47582a652686b2885f959ffd895b30e184842403990ef", res.PrevHash.StringLE()) + assert.Equal(t, "b8e923148dede20901d6fb225579f6d430cc58f24461d1b0f860ee32abbfcc8d", res.MerkleRoot.StringLE()) assert.Equal(t, 1, len(res.Transactions)) - assert.Equal(t, "115975f7d1e9c4577ec839c6ea4ae32727616284e2d7cdc5a49e4e421b32e505", res.Transactions[0].Hash().StringLE()) + assert.Equal(t, "96ef00d2efe03101f5b302f7fc3c8fcd22688944bdc83ab99071d77edbb08581", res.Transactions[0].Hash().StringLE()) }, }, { @@ -156,49 +156,49 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ invoke: func(c *Client) (i interface{}, err error) { return c.GetBlockByIndexVerbose(202) }, - serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0x75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45","size":765,"version":0,"nextblockhash":"0xec27fed4ff8ad6a87bdd29aecee43e9ecb4e336321dac875d0b14d2aab1c5798","previousblockhash":"0x6432511ffdb7da7766fac3591efba688793b5368789bdb374de26eaa136bf039","merkleroot":"0xcd9211a3b642d13d1309817b8a575e4ce00e53947912b34aa0ff61f024faf405","time":1588259741,"index":202,"consensus_data":{"primary":0,"nonce":"0000000000000457"},"nextconsensus":"Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy","confirmations":6,"script":{"invocation":"0c404617b6788538326383015c44ffddd4a05a4e200b65a26fc84234ae8b1e28ef27b7f139dc498c58071193d530ba83081701290eba8f7108397499f5556c16e3780c402131f2bdcc494c73a379e86c46f9e9fe9899a05b23928926b1eaaf816928e160fe971b82263aa1e7efa5f7e46bf99de735fc4fc5aeb81edfdc6a9b2e9fcfa1000c408cbae1582bb9d82de9ff030b8c729737f2157844c0ca29edcdbfed1dd5e2473e0061f0dc29412477417e2c1f7c55443f11b9bd6e0d0856d1ec00240be1b9b9a70c4034d1055531cf0522ac7e5dcd817cf3cd86997ae38da806dc789b1f16eb0005f00b9bc29f7372bb43a8fed040c6763b162c8a0d8e2d0b2d7476e22e0b2b776010","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"},"tx":[{"sys_fee":"0","net_fee":"0","txid":"0x115975f7d1e9c4577ec839c6ea4ae32727616284e2d7cdc5a49e4e421b32e505","size":238,"type":"ContractTransaction","version":0,"nonce":3,"sender":"ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR","valid_until_block":1200,"attributes":[],"cosigners":[],"vin":[{"txid":"0x1f08a32642a43e3f06b3b9a9355ed274c52de85a886841a2aef7edd94d1dc3f6","vout":0}],"vout":[{"address":"ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR","asset":"0x7dc12f8835b085d468ddbab3f7152c0e2f5679b5815b2028685abb4608e7b7dc","n":0,"value":"99999000"}],"scripts":[{"invocation":"0c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff","verification":"0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"}]}]}}`, + serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0xcbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86","size":781,"version":0,"nextblockhash":"0x13283c93aec07dc90be3ddd65e2de15e9212f1b3205303f688d6df85129f6b22","previousblockhash":"0x93b540424c1173e487a47582a652686b2885f959ffd895b30e184842403990ef","merkleroot":"0xb8e923148dede20901d6fb225579f6d430cc58f24461d1b0f860ee32abbfcc8d","time":1589300496,"index":202,"consensus_data":{"primary":0,"nonce":"0000000000000457"},"nextconsensus":"AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL","confirmations":6,"script":{"invocation":"0c403620ef8f02d7884c553fb6c54d2fe717cfddd9450886c5fc88a669a29a82fa1a7c715076996567a5a56747f20f10d7e4db071d73b306ccbf17f9a916fcfa1d020c4099e27d87bbb3fb4ce1c77dca85cf3eac46c9c3de87d8022ef7ad2b0a2bb980339293849cf85e5a0a5615ea7bc5bb0a7f28e31f278dc19d628f64c49b888df4c60c40616eefc9286843c2f3f2cf1815988356e409b3f10ffaf60b3468dc0a92dd929cbc8d5da74052c303e7474412f6beaddd551e9056c4e7a5fccdc06107e48f3fe10c40fd2d25d4156e969345c0522669b509e5ced70e4265066eadaf85eea3919d5ded525f8f52d6f0dfa0186c964dd0302fca5bc2dc0540b4ed21085be478c3123996","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb"},"tx":[{"txid":"0x96ef00d2efe03101f5b302f7fc3c8fcd22688944bdc83ab99071d77edbb08581","size":254,"type":"ContractTransaction","version":0,"nonce":3,"sender":"ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG","sys_fee":"0","net_fee":"0","valid_until_block":1200,"attributes":[],"cosigners":[],"vin":[{"txid":"0x33e045101301854a0e07ff96a92ca1ba9b23c19501f1b7eb15ae9eea07b5f370","vout":0}],"vout":[{"address":"ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG","asset":"0x1a5e0e3eac2abced7de9ee2de0820a5c85e63756fcdfc29b82fead86a7c07c78","n":0,"value":"99999000"}],"scripts":[{"invocation":"0c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb","verification":"0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"}]}]}}`, result: func(c *Client) interface{} { - hash, err := util.Uint256DecodeStringLE("75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45") + hash, err := util.Uint256DecodeStringLE("cbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86") if err != nil { panic(err) } - nextBlockHash, err := util.Uint256DecodeStringLE("ec27fed4ff8ad6a87bdd29aecee43e9ecb4e336321dac875d0b14d2aab1c5798") + nextBlockHash, err := util.Uint256DecodeStringLE("13283c93aec07dc90be3ddd65e2de15e9212f1b3205303f688d6df85129f6b22") if err != nil { panic(err) } - prevBlockHash, err := util.Uint256DecodeStringLE("6432511ffdb7da7766fac3591efba688793b5368789bdb374de26eaa136bf039") + prevBlockHash, err := util.Uint256DecodeStringLE("93b540424c1173e487a47582a652686b2885f959ffd895b30e184842403990ef") if err != nil { panic(err) } - merkleRoot, err := util.Uint256DecodeStringLE("cd9211a3b642d13d1309817b8a575e4ce00e53947912b34aa0ff61f024faf405") + merkleRoot, err := util.Uint256DecodeStringLE("b8e923148dede20901d6fb225579f6d430cc58f24461d1b0f860ee32abbfcc8d") if err != nil { panic(err) } - invScript, err := hex.DecodeString("0c404617b6788538326383015c44ffddd4a05a4e200b65a26fc84234ae8b1e28ef27b7f139dc498c58071193d530ba83081701290eba8f7108397499f5556c16e3780c402131f2bdcc494c73a379e86c46f9e9fe9899a05b23928926b1eaaf816928e160fe971b82263aa1e7efa5f7e46bf99de735fc4fc5aeb81edfdc6a9b2e9fcfa1000c408cbae1582bb9d82de9ff030b8c729737f2157844c0ca29edcdbfed1dd5e2473e0061f0dc29412477417e2c1f7c55443f11b9bd6e0d0856d1ec00240be1b9b9a70c4034d1055531cf0522ac7e5dcd817cf3cd86997ae38da806dc789b1f16eb0005f00b9bc29f7372bb43a8fed040c6763b162c8a0d8e2d0b2d7476e22e0b2b776010") + invScript, err := hex.DecodeString("0c403620ef8f02d7884c553fb6c54d2fe717cfddd9450886c5fc88a669a29a82fa1a7c715076996567a5a56747f20f10d7e4db071d73b306ccbf17f9a916fcfa1d020c4099e27d87bbb3fb4ce1c77dca85cf3eac46c9c3de87d8022ef7ad2b0a2bb980339293849cf85e5a0a5615ea7bc5bb0a7f28e31f278dc19d628f64c49b888df4c60c40616eefc9286843c2f3f2cf1815988356e409b3f10ffaf60b3468dc0a92dd929cbc8d5da74052c303e7474412f6beaddd551e9056c4e7a5fccdc06107e48f3fe10c40fd2d25d4156e969345c0522669b509e5ced70e4265066eadaf85eea3919d5ded525f8f52d6f0dfa0186c964dd0302fca5bc2dc0540b4ed21085be478c3123996") if err != nil { panic(err) } - verifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb") + verifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb") if err != nil { panic(err) } - sender, err := address.StringToUint160("ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR") + sender, err := address.StringToUint160("ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG") if err != nil { panic(err) } - txInvScript, err := hex.DecodeString("0c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff") + txInvScript, err := hex.DecodeString("0c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb") if err != nil { panic(err) } - txVerifScript, err := hex.DecodeString("0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4") + txVerifScript, err := hex.DecodeString("0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4") if err != nil { panic(err) } - vin, err := util.Uint256DecodeStringLE("1f08a32642a43e3f06b3b9a9355ed274c52de85a886841a2aef7edd94d1dc3f6") + vin, err := util.Uint256DecodeStringLE("33e045101301854a0e07ff96a92ca1ba9b23c19501f1b7eb15ae9eea07b5f370") if err != nil { panic(err) } - outAddress, err := address.StringToUint160("ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR") + outAddress, err := address.StringToUint160("ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG") if err != nil { panic(err) } @@ -231,14 +231,14 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ _ = tx.Hash() return &result.Block{ Hash: hash, - Size: 765, + Size: 781, Version: 0, NextBlockHash: &nextBlockHash, PreviousBlockHash: prevBlockHash, MerkleRoot: merkleRoot, - Time: 1588259741, + Time: 1589300496, Index: 202, - NextConsensus: "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy", + NextConsensus: "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL", Confirmations: 6, ConsensusData: result.ConsensusData{ PrimaryIndex: 0, @@ -248,90 +248,84 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ InvocationScript: invScript, VerificationScript: verifScript, }, - Tx: []result.Tx{{ - Transaction: tx, - Fees: result.Fees{ - SysFee: 0, - NetFee: 0, - }, - }}, + Tx: []*transaction.Transaction{tx}, } }, }, { name: "byHash_positive", invoke: func(c *Client) (interface{}, error) { - hash, err := util.Uint256DecodeStringLE("45bc7f077a4381c9836164b242af97ffa59e5d233ccba4929796ce873474ab75") + hash, err := util.Uint256DecodeStringLE("86fe1061140b2ea791b0739fb9732abc6e5e47de4927228a1ac41de3d93eb7cb") if err != nil { panic(err) } return c.GetBlockByHash(hash) }, - serverResponse: `{"id":1,"jsonrpc":"2.0","result":"0000000039f06b13aa6ee24d37db9b7868533b7988a6fb1e59c3fa6677dab7fd1f51326405f4fa24f061ffa04ab3127994530ee04c5e578a7b8109133dd142b6a31192cd9debaa5e00000000ca000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c404617b6788538326383015c44ffddd4a05a4e200b65a26fc84234ae8b1e28ef27b7f139dc498c58071193d530ba83081701290eba8f7108397499f5556c16e3780c402131f2bdcc494c73a379e86c46f9e9fe9899a05b23928926b1eaaf816928e160fe971b82263aa1e7efa5f7e46bf99de735fc4fc5aeb81edfdc6a9b2e9fcfa1000c408cbae1582bb9d82de9ff030b8c729737f2157844c0ca29edcdbfed1dd5e2473e0061f0dc29412477417e2c1f7c55443f11b9bd6e0d0856d1ec00240be1b9b9a70c4034d1055531cf0522ac7e5dcd817cf3cd86997ae38da806dc789b1f16eb0005f00b9bc29f7372bb43a8fed040c6763b162c8a0d8e2d0b2d7476e22e0b2b77601094130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb0200570400000000000080000300000075a94799633ed955dd85a8af314a5b435ab51903b0040000000001f6c31d4dd9edf7aea24168885ae82dc574d25e35a9b9b3063f3ea44226a3081f000001dcb7e70846bb5a6828205b81b579562f0e2c15f7b3badd68d485b035882fc17d00184a27db86230075a94799633ed955dd85a8af314a5b435ab5190301420c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"}`, + serverResponse: `{"id":1,"jsonrpc":"2.0","result":"00000000ef9039404248180eb395d8ff59f985286b6852a68275a487e473114c4240b5938dccbfab32ee60f8b0d16144f258cc30d4f6795522fbd60109e2ed8d1423e9b810cdba5e00000000ca000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c403620ef8f02d7884c553fb6c54d2fe717cfddd9450886c5fc88a669a29a82fa1a7c715076996567a5a56747f20f10d7e4db071d73b306ccbf17f9a916fcfa1d020c4099e27d87bbb3fb4ce1c77dca85cf3eac46c9c3de87d8022ef7ad2b0a2bb980339293849cf85e5a0a5615ea7bc5bb0a7f28e31f278dc19d628f64c49b888df4c60c40616eefc9286843c2f3f2cf1815988356e409b3f10ffaf60b3468dc0a92dd929cbc8d5da74052c303e7474412f6beaddd551e9056c4e7a5fccdc06107e48f3fe10c40fd2d25d4156e969345c0522669b509e5ced70e4265066eadaf85eea3919d5ded525f8f52d6f0dfa0186c964dd0302fca5bc2dc0540b4ed21085be478c312399694130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb02005704000000000000800003000000316e851039019d39dfc2c37d6c3fee19fd58098700000000000000000000000000000000b004000000000170f3b507ea9eae15ebb7f10195c1239bbaa12ca996ff070e4a8501131045e033000001787cc0a786adfe829bc2dffc5637e6855c0a82e02deee97dedbc2aac3e0e5e1a00184a27db862300316e851039019d39dfc2c37d6c3fee19fd58098701420c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"}`, result: func(c *Client) interface{} { return &block.Block{} }, check: func(t *testing.T, c *Client, result interface{}) { res, ok := result.(*block.Block) require.True(t, ok) assert.Equal(t, uint32(0), res.Version) - assert.Equal(t, "75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45", res.Hash().StringLE()) - assert.Equal(t, "6432511ffdb7da7766fac3591efba688793b5368789bdb374de26eaa136bf039", res.PrevHash.StringLE()) - assert.Equal(t, "cd9211a3b642d13d1309817b8a575e4ce00e53947912b34aa0ff61f024faf405", res.MerkleRoot.StringLE()) + assert.Equal(t, "cbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86", res.Hash().StringLE()) + assert.Equal(t, "93b540424c1173e487a47582a652686b2885f959ffd895b30e184842403990ef", res.PrevHash.StringLE()) + assert.Equal(t, "b8e923148dede20901d6fb225579f6d430cc58f24461d1b0f860ee32abbfcc8d", res.MerkleRoot.StringLE()) assert.Equal(t, 1, len(res.Transactions)) - assert.Equal(t, "115975f7d1e9c4577ec839c6ea4ae32727616284e2d7cdc5a49e4e421b32e505", res.Transactions[0].Hash().StringLE()) + assert.Equal(t, "96ef00d2efe03101f5b302f7fc3c8fcd22688944bdc83ab99071d77edbb08581", res.Transactions[0].Hash().StringLE()) }, }, { name: "byHash_verbose_positive", invoke: func(c *Client) (i interface{}, err error) { - hash, err := util.Uint256DecodeStringLE("45bc7f077a4381c9836164b242af97ffa59e5d233ccba4929796ce873474ab75") + hash, err := util.Uint256DecodeStringLE("86fe1061140b2ea791b0739fb9732abc6e5e47de4927228a1ac41de3d93eb7cb") if err != nil { panic(err) } return c.GetBlockByHashVerbose(hash) }, - serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0x75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45","size":765,"version":0,"nextblockhash":"0xec27fed4ff8ad6a87bdd29aecee43e9ecb4e336321dac875d0b14d2aab1c5798","previousblockhash":"0x6432511ffdb7da7766fac3591efba688793b5368789bdb374de26eaa136bf039","merkleroot":"0xcd9211a3b642d13d1309817b8a575e4ce00e53947912b34aa0ff61f024faf405","time":1588259741,"index":202,"consensus_data":{"primary":0,"nonce":"0000000000000457"},"nextconsensus":"Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy","confirmations":6,"script":{"invocation":"0c404617b6788538326383015c44ffddd4a05a4e200b65a26fc84234ae8b1e28ef27b7f139dc498c58071193d530ba83081701290eba8f7108397499f5556c16e3780c402131f2bdcc494c73a379e86c46f9e9fe9899a05b23928926b1eaaf816928e160fe971b82263aa1e7efa5f7e46bf99de735fc4fc5aeb81edfdc6a9b2e9fcfa1000c408cbae1582bb9d82de9ff030b8c729737f2157844c0ca29edcdbfed1dd5e2473e0061f0dc29412477417e2c1f7c55443f11b9bd6e0d0856d1ec00240be1b9b9a70c4034d1055531cf0522ac7e5dcd817cf3cd86997ae38da806dc789b1f16eb0005f00b9bc29f7372bb43a8fed040c6763b162c8a0d8e2d0b2d7476e22e0b2b776010","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"},"tx":[{"sys_fee":"0","net_fee":"0","txid":"0x115975f7d1e9c4577ec839c6ea4ae32727616284e2d7cdc5a49e4e421b32e505","size":238,"type":"ContractTransaction","version":0,"nonce":3,"sender":"ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR","valid_until_block":1200,"attributes":[],"cosigners":[],"vin":[{"txid":"0x1f08a32642a43e3f06b3b9a9355ed274c52de85a886841a2aef7edd94d1dc3f6","vout":0}],"vout":[{"address":"ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR","asset":"0x7dc12f8835b085d468ddbab3f7152c0e2f5679b5815b2028685abb4608e7b7dc","n":0,"value":"99999000"}],"scripts":[{"invocation":"0c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff","verification":"0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"}]}]}}`, + serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0xcbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86","size":781,"version":0,"nextblockhash":"0x13283c93aec07dc90be3ddd65e2de15e9212f1b3205303f688d6df85129f6b22","previousblockhash":"0x93b540424c1173e487a47582a652686b2885f959ffd895b30e184842403990ef","merkleroot":"0xb8e923148dede20901d6fb225579f6d430cc58f24461d1b0f860ee32abbfcc8d","time":1589300496,"index":202,"consensus_data":{"primary":0,"nonce":"0000000000000457"},"nextconsensus":"AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL","confirmations":6,"script":{"invocation":"0c403620ef8f02d7884c553fb6c54d2fe717cfddd9450886c5fc88a669a29a82fa1a7c715076996567a5a56747f20f10d7e4db071d73b306ccbf17f9a916fcfa1d020c4099e27d87bbb3fb4ce1c77dca85cf3eac46c9c3de87d8022ef7ad2b0a2bb980339293849cf85e5a0a5615ea7bc5bb0a7f28e31f278dc19d628f64c49b888df4c60c40616eefc9286843c2f3f2cf1815988356e409b3f10ffaf60b3468dc0a92dd929cbc8d5da74052c303e7474412f6beaddd551e9056c4e7a5fccdc06107e48f3fe10c40fd2d25d4156e969345c0522669b509e5ced70e4265066eadaf85eea3919d5ded525f8f52d6f0dfa0186c964dd0302fca5bc2dc0540b4ed21085be478c3123996","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb"},"tx":[{"txid":"0x96ef00d2efe03101f5b302f7fc3c8fcd22688944bdc83ab99071d77edbb08581","size":254,"type":"ContractTransaction","version":0,"nonce":3,"sender":"ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG","sys_fee":"0","net_fee":"0","valid_until_block":1200,"attributes":[],"cosigners":[],"vin":[{"txid":"0x33e045101301854a0e07ff96a92ca1ba9b23c19501f1b7eb15ae9eea07b5f370","vout":0}],"vout":[{"address":"ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG","asset":"0x1a5e0e3eac2abced7de9ee2de0820a5c85e63756fcdfc29b82fead86a7c07c78","n":0,"value":"99999000"}],"scripts":[{"invocation":"0c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb","verification":"0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"}]}]}}`, result: func(c *Client) interface{} { - hash, err := util.Uint256DecodeStringLE("75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45") + hash, err := util.Uint256DecodeStringLE("cbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86") if err != nil { panic(err) } - nextBlockHash, err := util.Uint256DecodeStringLE("ec27fed4ff8ad6a87bdd29aecee43e9ecb4e336321dac875d0b14d2aab1c5798") + nextBlockHash, err := util.Uint256DecodeStringLE("13283c93aec07dc90be3ddd65e2de15e9212f1b3205303f688d6df85129f6b22") if err != nil { panic(err) } - prevBlockHash, err := util.Uint256DecodeStringLE("6432511ffdb7da7766fac3591efba688793b5368789bdb374de26eaa136bf039") + prevBlockHash, err := util.Uint256DecodeStringLE("93b540424c1173e487a47582a652686b2885f959ffd895b30e184842403990ef") if err != nil { panic(err) } - merkleRoot, err := util.Uint256DecodeStringLE("cd9211a3b642d13d1309817b8a575e4ce00e53947912b34aa0ff61f024faf405") + merkleRoot, err := util.Uint256DecodeStringLE("b8e923148dede20901d6fb225579f6d430cc58f24461d1b0f860ee32abbfcc8d") if err != nil { panic(err) } - invScript, err := hex.DecodeString("0c404617b6788538326383015c44ffddd4a05a4e200b65a26fc84234ae8b1e28ef27b7f139dc498c58071193d530ba83081701290eba8f7108397499f5556c16e3780c402131f2bdcc494c73a379e86c46f9e9fe9899a05b23928926b1eaaf816928e160fe971b82263aa1e7efa5f7e46bf99de735fc4fc5aeb81edfdc6a9b2e9fcfa1000c408cbae1582bb9d82de9ff030b8c729737f2157844c0ca29edcdbfed1dd5e2473e0061f0dc29412477417e2c1f7c55443f11b9bd6e0d0856d1ec00240be1b9b9a70c4034d1055531cf0522ac7e5dcd817cf3cd86997ae38da806dc789b1f16eb0005f00b9bc29f7372bb43a8fed040c6763b162c8a0d8e2d0b2d7476e22e0b2b776010") + invScript, err := hex.DecodeString("0c403620ef8f02d7884c553fb6c54d2fe717cfddd9450886c5fc88a669a29a82fa1a7c715076996567a5a56747f20f10d7e4db071d73b306ccbf17f9a916fcfa1d020c4099e27d87bbb3fb4ce1c77dca85cf3eac46c9c3de87d8022ef7ad2b0a2bb980339293849cf85e5a0a5615ea7bc5bb0a7f28e31f278dc19d628f64c49b888df4c60c40616eefc9286843c2f3f2cf1815988356e409b3f10ffaf60b3468dc0a92dd929cbc8d5da74052c303e7474412f6beaddd551e9056c4e7a5fccdc06107e48f3fe10c40fd2d25d4156e969345c0522669b509e5ced70e4265066eadaf85eea3919d5ded525f8f52d6f0dfa0186c964dd0302fca5bc2dc0540b4ed21085be478c3123996") if err != nil { panic(err) } - verifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb") + verifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb") if err != nil { panic(err) } - sender, err := address.StringToUint160("ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR") + sender, err := address.StringToUint160("ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG") if err != nil { panic(err) } - txInvScript, err := hex.DecodeString("0c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff") + txInvScript, err := hex.DecodeString("0c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb") if err != nil { panic(err) } - txVerifScript, err := hex.DecodeString("0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4") + txVerifScript, err := hex.DecodeString("0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4") if err != nil { panic(err) } - vin, err := util.Uint256DecodeStringLE("1f08a32642a43e3f06b3b9a9355ed274c52de85a886841a2aef7edd94d1dc3f6") + vin, err := util.Uint256DecodeStringLE("33e045101301854a0e07ff96a92ca1ba9b23c19501f1b7eb15ae9eea07b5f370") if err != nil { panic(err) } - outAddress, err := address.StringToUint160("ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR") + outAddress, err := address.StringToUint160("ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG") if err != nil { panic(err) } @@ -364,14 +358,14 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ _ = tx.Hash() return &result.Block{ Hash: hash, - Size: 765, + Size: 781, Version: 0, NextBlockHash: &nextBlockHash, PreviousBlockHash: prevBlockHash, MerkleRoot: merkleRoot, - Time: 1588259741, + Time: 1589300496, Index: 202, - NextConsensus: "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy", + NextConsensus: "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL", Confirmations: 6, ConsensusData: result.ConsensusData{ PrimaryIndex: 0, @@ -381,13 +375,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ InvocationScript: invScript, VerificationScript: verifScript, }, - Tx: []result.Tx{{ - Transaction: tx, - Fees: result.Fees{ - SysFee: 0, - NetFee: 0, - }, - }}, + Tx: []*transaction.Transaction{tx}, } }, }, @@ -701,19 +689,19 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ { name: "positive", invoke: func(c *Client) (i interface{}, err error) { - hash, err := util.Uint256DecodeStringLE("05e5321b424e9ea4c5cdd7e28462612727e34aeac639c87e57c4e9d1f7755911") + hash, err := util.Uint256DecodeStringLE("8185b0db7ed77190b93ac8bd44896822cd8f3cfcf702b3f50131e0efd200ef96") if err != nil { panic(err) } return c.GetRawTransaction(hash) }, - serverResponse: `{"id":1,"jsonrpc":"2.0","result":"80000300000075a94799633ed955dd85a8af314a5b435ab51903b0040000000001f6c31d4dd9edf7aea24168885ae82dc574d25e35a9b9b3063f3ea44226a3081f000001dcb7e70846bb5a6828205b81b579562f0e2c15f7b3badd68d485b035882fc17d00184a27db86230075a94799633ed955dd85a8af314a5b435ab5190301420c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"}`, + serverResponse: `{"id":1,"jsonrpc":"2.0","result":"800003000000316e851039019d39dfc2c37d6c3fee19fd58098700000000000000000000000000000000b004000000000170f3b507ea9eae15ebb7f10195c1239bbaa12ca996ff070e4a8501131045e033000001787cc0a786adfe829bc2dffc5637e6855c0a82e02deee97dedbc2aac3e0e5e1a00184a27db862300316e851039019d39dfc2c37d6c3fee19fd58098701420c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"}`, result: func(c *Client) interface{} { return &transaction.Transaction{} }, check: func(t *testing.T, c *Client, result interface{}) { res, ok := result.(*transaction.Transaction) require.True(t, ok) assert.Equal(t, uint8(0), res.Version) - assert.Equal(t, "05e5321b424e9ea4c5cdd7e28462612727e34aeac639c87e57c4e9d1f7755911", res.Hash().StringBE()) + assert.Equal(t, "8185b0db7ed77190b93ac8bd44896822cd8f3cfcf702b3f50131e0efd200ef96", res.Hash().StringBE()) assert.Equal(t, transaction.ContractType, res.Type) assert.Equal(t, false, res.Trimmed) }, @@ -721,35 +709,35 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ { name: "verbose_positive", invoke: func(c *Client) (interface{}, error) { - hash, err := util.Uint256DecodeStringLE("05e5321b424e9ea4c5cdd7e28462612727e34aeac639c87e57c4e9d1f7755911") + hash, err := util.Uint256DecodeStringLE("8185b0db7ed77190b93ac8bd44896822cd8f3cfcf702b3f50131e0efd200ef96") if err != nil { panic(err) } return c.GetRawTransactionVerbose(hash) }, - serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"sys_fee":"0","net_fee":"0","blockhash":"0x75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45","confirmations":8,"blocktime":1588259741,"txid":"0x115975f7d1e9c4577ec839c6ea4ae32727616284e2d7cdc5a49e4e421b32e505","size":238,"type":"ContractTransaction","version":0,"nonce":3,"sender":"ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR","valid_until_block":1200,"attributes":[],"cosigners":[],"vin":[{"txid":"0x1f08a32642a43e3f06b3b9a9355ed274c52de85a886841a2aef7edd94d1dc3f6","vout":0}],"vout":[{"address":"ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR","asset":"0x7dc12f8835b085d468ddbab3f7152c0e2f5679b5815b2028685abb4608e7b7dc","n":0,"value":"99999000"}],"scripts":[{"invocation":"0c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff","verification":"0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"}]}}`, + serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"blockhash":"0xcbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86","confirmations":8,"blocktime":1589300496,"txid":"0x96ef00d2efe03101f5b302f7fc3c8fcd22688944bdc83ab99071d77edbb08581","size":254,"type":"ContractTransaction","version":0,"nonce":3,"sender":"ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG","sys_fee":"0","net_fee":"0","valid_until_block":1200,"attributes":[],"cosigners":[],"vin":[{"txid":"0x33e045101301854a0e07ff96a92ca1ba9b23c19501f1b7eb15ae9eea07b5f370","vout":0}],"vout":[{"address":"ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG","asset":"0x1a5e0e3eac2abced7de9ee2de0820a5c85e63756fcdfc29b82fead86a7c07c78","n":0,"value":"99999000"}],"scripts":[{"invocation":"0c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb","verification":"0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"}]}}`, result: func(c *Client) interface{} { - blockHash, err := util.Uint256DecodeStringLE("75ab743487ce969792a4cb3c235d9ea5ff97af42b2646183c981437a077fbc45") + blockHash, err := util.Uint256DecodeStringLE("cbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86") if err != nil { panic(err) } - sender, err := address.StringToUint160("ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR") + sender, err := address.StringToUint160("ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG") if err != nil { panic(err) } - invocation, err := hex.DecodeString("0c40bfce1ead7d53339440bb29745eed4ad9840875de4f970950065291e7a14cbd249bfbf777d9a997c5e00bbc08e8ce9fdd2cd13c45c3585b4939599ff84c6149ff") + invocation, err := hex.DecodeString("0c402caebbee911a1f159aa05ab40093d086090a817e837f3f87e8b3e47f6b083649137770f6dda0349ddd611bc47402aca457a89b3b7b0076307ab6a47fd57048eb") if err != nil { panic(err) } - verification, err := hex.DecodeString("0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4") + verification, err := hex.DecodeString("0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4") if err != nil { panic(err) } - vin, err := util.Uint256DecodeStringLE("1f08a32642a43e3f06b3b9a9355ed274c52de85a886841a2aef7edd94d1dc3f6") + vin, err := util.Uint256DecodeStringLE("33e045101301854a0e07ff96a92ca1ba9b23c19501f1b7eb15ae9eea07b5f370") if err != nil { panic(err) } - outAddress, err := address.StringToUint160("ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR") + outAddress, err := address.StringToUint160("ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG") if err != nil { panic(err) } @@ -784,11 +772,9 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ return &result.TransactionOutputRaw{ Transaction: tx, TransactionMetadata: result.TransactionMetadata{ - SysFee: 0, - NetFee: 0, Blockhash: blockHash, Confirmations: 8, - Timestamp: uint64(1588259741), + Timestamp: uint64(1589300496), }, } }, diff --git a/pkg/rpc/response/result/block.go b/pkg/rpc/response/result/block.go index ccdef6fd5..3e18d6133 100644 --- a/pkg/rpc/response/result/block.go +++ b/pkg/rpc/response/result/block.go @@ -1,8 +1,6 @@ package result import ( - "encoding/json" - "errors" "fmt" "github.com/nspcc-dev/neo-go/pkg/core/block" @@ -14,19 +12,6 @@ import ( ) type ( - // Tx wrapper used for the representation of - // transaction on the RPC Server. - Tx struct { - *transaction.Transaction - Fees - } - - // Fees is an auxilliary struct for proper Tx marshaling. - Fees struct { - SysFee util.Fixed8 `json:"sys_fee"` - NetFee util.Fixed8 `json:"net_fee"` - } - // ConsensusData is a wrapper for block.ConsensusData ConsensusData struct { PrimaryIndex uint32 `json:"primary"` @@ -51,7 +36,7 @@ type ( Script transaction.Witness `json:"script"` - Tx []Tx `json:"tx"` + Tx []*transaction.Transaction `json:"tx"` } ) @@ -74,7 +59,7 @@ func NewBlock(b *block.Block, chain blockchainer.Blockchainer) Block { Script: b.Script, - Tx: make([]Tx, 0, len(b.Transactions)), + Tx: b.Transactions, } hash := chain.GetHeaderHash(int(b.Index) + 1) @@ -82,60 +67,5 @@ func NewBlock(b *block.Block, chain blockchainer.Blockchainer) Block { res.NextBlockHash = &hash } - for i := range b.Transactions { - res.Tx = append(res.Tx, Tx{ - Transaction: b.Transactions[i], - Fees: Fees{ - SysFee: chain.SystemFee(b.Transactions[i]), - NetFee: chain.NetworkFee(b.Transactions[i]), - }, - }) - } - return res } - -// MarshalJSON implements json.Marshaler interface. -func (t Tx) MarshalJSON() ([]byte, error) { - output, err := json.Marshal(&Fees{ - SysFee: t.SysFee, - NetFee: t.NetFee, - }) - if err != nil { - return nil, err - } - txBytes, err := json.Marshal(t.Transaction) - if err != nil { - return nil, err - } - - // We have to keep both transaction.Transaction and tx at the same level in json in order to match C# API, - // so there's no way to marshall Tx correctly with standard json.Marshaller tool. - if output[len(output)-1] != '}' || txBytes[0] != '{' { - return nil, errors.New("can't merge internal jsons") - } - output[len(output)-1] = ',' - output = append(output, txBytes[1:]...) - return output, nil -} - -// UnmarshalJSON implements json.Marshaler interface. -func (t *Tx) UnmarshalJSON(data []byte) error { - // As transaction.Transaction and tx are at the same level in json, do unmarshalling - // separately for both structs. - output := new(Fees) - err := json.Unmarshal(data, output) - if err != nil { - return err - } - t.SysFee = output.SysFee - t.NetFee = output.NetFee - - transaction := new(transaction.Transaction) - err = json.Unmarshal(data, transaction) - if err != nil { - return err - } - t.Transaction = transaction - return nil -} diff --git a/pkg/rpc/response/result/tx_raw_output.go b/pkg/rpc/response/result/tx_raw_output.go index 886d865ed..ae47dda50 100644 --- a/pkg/rpc/response/result/tx_raw_output.go +++ b/pkg/rpc/response/result/tx_raw_output.go @@ -19,8 +19,6 @@ type TransactionOutputRaw struct { // TransactionMetadata is an auxilliary struct for proper TransactionOutputRaw marshaling. type TransactionMetadata struct { - SysFee util.Fixed8 `json:"sys_fee"` - NetFee util.Fixed8 `json:"net_fee"` Blockhash util.Uint256 `json:"blockhash,omitempty"` Confirmations int `json:"confirmations,omitempty"` Timestamp uint64 `json:"blocktime,omitempty"` @@ -37,8 +35,6 @@ func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, return TransactionOutputRaw{ Transaction: tx, TransactionMetadata: TransactionMetadata{ - SysFee: chain.SystemFee(tx), - NetFee: chain.NetworkFee(tx), Blockhash: header.Hash(), Confirmations: confirmations, Timestamp: header.Timestamp, @@ -49,8 +45,6 @@ func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, // MarshalJSON implements json.Marshaler interface. func (t TransactionOutputRaw) MarshalJSON() ([]byte, error) { output, err := json.Marshal(TransactionMetadata{ - SysFee: t.SysFee, - NetFee: t.NetFee, Blockhash: t.Blockhash, Confirmations: t.Confirmations, Timestamp: t.Timestamp, @@ -82,8 +76,6 @@ func (t *TransactionOutputRaw) UnmarshalJSON(data []byte) error { if err != nil { return err } - t.SysFee = output.SysFee - t.NetFee = output.NetFee t.Blockhash = output.Blockhash t.Confirmations = output.Confirmations t.Timestamp = output.Timestamp diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 817cba0ba..09c8dd11d 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -798,7 +798,7 @@ func (s *Server) getBlockSysFee(reqParams request.Params) (interface{}, *respons var blockSysFee util.Fixed8 for _, tx := range block.Transactions { - blockSysFee += s.chain.SystemFee(tx) + blockSysFee += tx.SystemFee } return blockSysFee, nil diff --git a/pkg/rpc/server/server_helper_test.go b/pkg/rpc/server/server_helper_test.go index c6ee3167e..d8a0baa3d 100644 --- a/pkg/rpc/server/server_helper_test.go +++ b/pkg/rpc/server/server_helper_test.go @@ -10,7 +10,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/storage" - "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/network" "github.com/nspcc-dev/neo-go/pkg/util" @@ -65,18 +64,10 @@ func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *httptest.Serv type FeerStub struct{} -func (fs *FeerStub) NetworkFee(*transaction.Transaction) util.Fixed8 { - return 0 -} - func (fs *FeerStub) IsLowPriority(util.Fixed8) bool { return false } -func (fs *FeerStub) FeePerByte(*transaction.Transaction) util.Fixed8 { - return 0 -} - -func (fs *FeerStub) SystemFee(*transaction.Transaction) util.Fixed8 { +func (fs *FeerStub) FeePerByte() util.Fixed8 { return 0 } diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 062c01770..db7cd3679 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -54,12 +54,12 @@ var rpcTestCases = map[string][]rpcTestCase{ "getapplicationlog": { { name: "positive", - params: `["396d55aa14b6cd428d793e9e740d24f93f62d7ddcdc0f4fdadd4dfd89bdabd83"]`, + params: `["0a0abf0188053113d0014e0cb9801d090a5d3e7640d76427fa1a3676e7cdf82e"]`, result: func(e *executor) interface{} { return &result.ApplicationLog{} }, check: func(t *testing.T, e *executor, acc interface{}) { res, ok := acc.(*result.ApplicationLog) require.True(t, ok) - expectedTxHash, err := util.Uint256DecodeStringLE("396d55aa14b6cd428d793e9e740d24f93f62d7ddcdc0f4fdadd4dfd89bdabd83") + expectedTxHash, err := util.Uint256DecodeStringLE("0a0abf0188053113d0014e0cb9801d090a5d3e7640d76427fa1a3676e7cdf82e") require.NoError(t, err) assert.Equal(t, expectedTxHash, res.TxHash) assert.Equal(t, 1, len(res.Executions)) @@ -170,11 +170,23 @@ var rpcTestCases = map[string][]rpcTestCase{ check: func(t *testing.T, e *executor, acc interface{}) { res, ok := acc.(*result.NEP5Balances) require.True(t, ok) + rubles, err := util.Uint160DecodeStringLE(testContractHash) + require.NoError(t, err) + expected := result.NEP5Balances{ + Balances: []result.NEP5Balance{{ + Asset: rubles, + Amount: "8.77", + LastUpdated: 208, + }, + { + Asset: e.chain.UtilityTokenHash(), + Amount: "10", + LastUpdated: 1, + }}, + Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(), + } require.Equal(t, testchain.PrivateKeyByID(0).Address(), res.Address) - require.Equal(t, 1, len(res.Balances)) - require.Equal(t, "8.77", res.Balances[0].Amount) - require.Equal(t, testContractHash, res.Balances[0].Asset.StringLE()) - require.Equal(t, uint32(208), res.Balances[0].LastUpdated) + require.ElementsMatch(t, expected.Balances, res.Balances) }, }, }, @@ -196,20 +208,56 @@ var rpcTestCases = map[string][]rpcTestCase{ check: func(t *testing.T, e *executor, acc interface{}) { res, ok := acc.(*result.NEP5Transfers) require.True(t, ok) - require.Equal(t, testchain.PrivateKeyByID(0).Address(), res.Address) - - assetHash, err := util.Uint160DecodeStringLE(testContractHash) + rublesHash, err := util.Uint160DecodeStringLE(testContractHash) require.NoError(t, err) - - require.Equal(t, 1, len(res.Received)) - require.Equal(t, "10", res.Received[0].Amount) - require.Equal(t, assetHash, res.Received[0].Asset) - require.Equal(t, address.Uint160ToString(assetHash), res.Received[0].Address) - - require.Equal(t, 1, len(res.Sent)) - require.Equal(t, "1.23", res.Sent[0].Amount) - require.Equal(t, assetHash, res.Sent[0].Asset) - require.Equal(t, testchain.PrivateKeyByID(1).Address(), res.Sent[0].Address) + blockSendRubles, err := e.chain.GetBlock(e.chain.GetHeaderHash(208)) + require.NoError(t, err) + require.Equal(t, 1, len(blockSendRubles.Transactions)) + txSendRublesHash := blockSendRubles.Transactions[0].Hash() + blockRecieveRubles, err := e.chain.GetBlock(e.chain.GetHeaderHash(207)) + require.NoError(t, err) + require.Equal(t, 2, len(blockRecieveRubles.Transactions)) + txRecieveRublesHash := blockRecieveRubles.Transactions[1].Hash() + blockRecieveGAS, err := e.chain.GetBlock(e.chain.GetHeaderHash(1)) + require.NoError(t, err) + require.Equal(t, 1, len(blockRecieveGAS.Transactions)) + txRecieveGASHash := blockRecieveGAS.Transactions[0].Hash() + require.NoError(t, err) + expected := result.NEP5Transfers{ + Sent: []result.NEP5Transfer{{ + Timestamp: blockSendRubles.Timestamp, + Asset: rublesHash, + Address: testchain.PrivateKeyByID(1).Address(), + Amount: "1.23", + Index: 208, + NotifyIndex: 0, + TxHash: txSendRublesHash, + }}, + Received: []result.NEP5Transfer{ + { + Timestamp: blockRecieveRubles.Timestamp, + Asset: rublesHash, + Address: address.Uint160ToString(rublesHash), + Amount: "10", + Index: 207, + NotifyIndex: 0, + TxHash: txRecieveRublesHash, + }, + { + Timestamp: blockRecieveGAS.Timestamp, + Asset: e.chain.UtilityTokenHash(), + Address: testchain.MultisigAddress(), + Amount: "10", + Index: 1, + NotifyIndex: 0, + TxHash: txRecieveGASHash, + }, + }, + Address: testchain.PrivateKeyByID(0).Address(), + } + require.Equal(t, expected.Address, res.Address) + require.ElementsMatch(t, expected.Sent, res.Sent) + require.ElementsMatch(t, expected.Received, res.Received) }, }, }, @@ -254,7 +302,7 @@ var rpcTestCases = map[string][]rpcTestCase{ "getassetstate": { { name: "positive", - params: `["8ef63ccd6f4ea20a93e7f4e84b2d43f778077612b241d617e42e1750cca4f2c5"]`, + params: `["f882fb865bab84b99623f21eedd902286af7da8d8a4609d7acefce04c851dc1c"]`, result: func(e *executor) interface{} { return &result.AssetState{} }, check: func(t *testing.T, e *executor, as interface{}) { res, ok := as.(*result.AssetState) @@ -327,24 +375,24 @@ var rpcTestCases = map[string][]rpcTestCase{ "getblock": { { name: "positive", - params: "[2, 1]", + params: "[3, 1]", result: func(e *executor) interface{} { return &result.Block{} }, check: func(t *testing.T, e *executor, blockRes interface{}) { res, ok := blockRes.(*result.Block) require.True(t, ok) - block, err := e.chain.GetBlock(e.chain.GetHeaderHash(2)) + block, err := e.chain.GetBlock(e.chain.GetHeaderHash(3)) require.NoErrorf(t, err, "could not get block") assert.Equal(t, block.Hash(), res.Hash) for i := range res.Tx { tx := res.Tx[i] - require.Equal(t, transaction.ContractType, tx.Transaction.Type) + require.Equal(t, transaction.ContractType, tx.Type) actualTx := block.Transactions[i] require.True(t, ok) - require.Equal(t, actualTx.Nonce, tx.Transaction.Nonce) - require.Equal(t, block.Transactions[i].Hash(), tx.Transaction.Hash()) + require.Equal(t, actualTx.Nonce, tx.Nonce) + require.Equal(t, block.Transactions[i].Hash(), tx.Hash()) } }, }, @@ -436,7 +484,7 @@ var rpcTestCases = map[string][]rpcTestCase{ var expectedBlockSysFee util.Fixed8 for _, tx := range block.Transactions { - expectedBlockSysFee += e.chain.SystemFee(tx) + expectedBlockSysFee += tx.SystemFee } return &expectedBlockSysFee }, @@ -473,7 +521,7 @@ var rpcTestCases = map[string][]rpcTestCase{ params: `["` + testchain.MultisigAddress() + `"]`, result: func(*executor) interface{} { // hash of the issueTx - h, _ := util.Uint256DecodeStringBE("3b76c9b726ffa9074a69441bf946c4c70b83474b3cf522ea3ba9dcd71c1a3db8") + h, _ := util.Uint256DecodeStringBE("d3a4f2249fe33b18bde73901c1ecc66200485f1c1dcd941b406a630b479090ae") amount := util.Fixed8FromInt64(1 * 8) // (endHeight - startHeight) * genAmount[0] return &result.ClaimableInfo{ Spents: []result.Claimable{ @@ -532,7 +580,7 @@ var rpcTestCases = map[string][]rpcTestCase{ "gettransactionheight": { { name: "positive", - params: `["a05ea6d90b761ec5430f29d25036fdad04efe731b6a5906f4fd1e19048dee0f2"]`, + params: `["792dfa667e204c41fe68437df9324b04b14bcc94bbf7c6108ef0067a196c7600"]`, result: func(e *executor) interface{} { h := 1 return &h @@ -744,7 +792,7 @@ var rpcTestCases = map[string][]rpcTestCase{ "sendrawtransaction": { { name: "positive", - params: `["80000b000000316e851039019d39dfc2c37d6c3fee19fd580987b0040000000001241a237db30af3b33d29518288e0c9b542475733f78f4c6d7416cba89c1f1a67010001dcb7e70846bb5a6828205b81b579562f0e2c15f7b3badd68d485b035882fc17d0030d3dec3862300316e851039019d39dfc2c37d6c3fee19fd58098701420c40c3c3fedb73e36a8e78bae80ba07c20b34f5af6bba36dccbe0cdc7d4e1237f85eec36e63cb762e1e6ce031a6c752e1ce19a3994d15191a6b75f1a02ede7f9d117290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`, + params: `["80000b000000316e851039019d39dfc2c37d6c3fee19fd5809870000000000000000a267050000000000b0040000000001232837446dce2cd43b7b340f72da323eac420cf4c0a0908dc38c08c5c3cbfd31010001787cc0a786adfe829bc2dffc5637e6855c0a82e02deee97dedbc2aac3e0e5e1a0030d3dec3862300316e851039019d39dfc2c37d6c3fee19fd58098701420c4074335c72529aabf9e4b22727a9ca8b851217cd2d6cb5d5634dbc6c60ab8dce225f90e208362805499cbc607bcd991a021f5e6a5e0b2f663ffb64fb3767966d88290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`, result: func(e *executor) interface{} { v := true return &v @@ -867,16 +915,26 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] checkErrGetResult(t, body, true) }) - wif := testchain.WIF(0) - acc, err := wallet.NewAccountFromWIF(wif) + priv0 := testchain.PrivateKeyByID(0) + acc0, err := wallet.NewAccountFromWIF(priv0.WIF()) require.NoError(t, err) + + addNetworkFee := func(tx *transaction.Transaction) { + size := io.GetVarSize(tx) + netFee, sizeDelta := core.CalculateNetworkFee(acc0.Contract.Script) + tx.NetworkFee += netFee + size += sizeDelta + tx.NetworkFee = tx.NetworkFee.Add(util.Fixed8(int64(size) * int64(chain.FeePerByte()))) + } + newTx := func() *transaction.Transaction { height := chain.BlockHeight() tx := transaction.NewContractTX() tx.Nonce = height + 1 tx.ValidUntilBlock = height + 10 - tx.Sender = acc.PrivateKey().GetScriptHash() - require.NoError(t, acc.SignTx(tx)) + tx.Sender = acc0.PrivateKey().GetScriptHash() + addNetworkFee(tx) + require.NoError(t, acc0.SignTx(tx)) return tx } @@ -905,7 +963,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] var res string err := json.Unmarshal(result, &res) require.NoErrorf(t, err, "could not parse response: %s", result) - assert.Equal(t, "400000000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000455b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e882a1227d2c7b226c616e67223a22656e222c226e616d65223a22416e745368617265227d5d0000c16ff28623000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000", res) + assert.Equal(t, "400000000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b000000000000000000000000000000000000000000455b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e882a1227d2c7b226c616e67223a22656e222c226e616d65223a22416e745368617265227d5d0000c16ff28623000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000", res) }) t.Run("getrawtransaction 2 arguments", func(t *testing.T) { @@ -917,7 +975,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] var res string err := json.Unmarshal(result, &res) require.NoErrorf(t, err, "could not parse response: %s", result) - assert.Equal(t, "400000000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000455b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e882a1227d2c7b226c616e67223a22656e222c226e616d65223a22416e745368617265227d5d0000c16ff28623000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000", res) + assert.Equal(t, "400000000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b000000000000000000000000000000000000000000455b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e882a1227d2c7b226c616e67223a22656e222c226e616d65223a22416e745368617265227d5d0000c16ff28623000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000", res) }) t.Run("getrawtransaction 2 arguments, verbose", func(t *testing.T) { @@ -1006,7 +1064,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] err := json.Unmarshal(res, &txOut) require.NoErrorf(t, err, "could not parse response: %s", res) assert.Equal(t, 0, txOut.N) - assert.Equal(t, "0xdcb7e70846bb5a6828205b81b579562f0e2c15f7b3badd68d485b035882fc17d", txOut.Asset) + assert.Equal(t, "0x787cc0a786adfe829bc2dffc5637e6855c0a82e02deee97dedbc2aac3e0e5e1a", txOut.Asset) assert.Equal(t, util.Fixed8FromInt64(100000000), txOut.Value) assert.Equal(t, testchain.MultisigAddress(), txOut.Address) }) diff --git a/pkg/rpc/server/testdata/testblocks.acc b/pkg/rpc/server/testdata/testblocks.acc index 0957d415dd50c03eac915046d44a90dc1a327748..9459598e4ac9f297ad50ccbc67f3055ec75eb2f9 100644 GIT binary patch literal 114007 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 QZiIg0b2DcB&n4pj1L*8rH2?qr literal 113765 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

Xg&{NzN0tfD(%!xC+NLkyv_K=FFKI>S?^~l@*Zt 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 diff --git a/pkg/smartcontract/context/context.go b/pkg/smartcontract/context/context.go index b9dc12966..c92b1fcd3 100644 --- a/pkg/smartcontract/context/context.go +++ b/pkg/smartcontract/context/context.go @@ -70,7 +70,7 @@ func (c *ParameterContext) GetWitness(ctr *wallet.Contract) (*transaction.Witnes // AddSignature adds a signature for the specified contract and public key. func (c *ParameterContext) AddSignature(ctr *wallet.Contract, pub *keys.PublicKey, sig []byte) error { item := c.getItemForContract(ctr) - if pubs, ok := vm.ParseMultiSigContract(ctr.Script); ok { + if _, pubs, ok := vm.ParseMultiSigContract(ctr.Script); ok { if item.GetSignature(pub) != nil { return errors.New("signature is already added") } diff --git a/pkg/vm/contract_checks.go b/pkg/vm/contract_checks.go index 257d3e3ec..e4acc3766 100644 --- a/pkg/vm/contract_checks.go +++ b/pkg/vm/contract_checks.go @@ -36,65 +36,65 @@ func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) { // IsMultiSigContract checks whether the passed script is a multi-signature // contract. func IsMultiSigContract(script []byte) bool { - _, ok := ParseMultiSigContract(script) + _, _, ok := ParseMultiSigContract(script) return ok } -// ParseMultiSigContract returns list of public keys from the verification -// script of the contract. -func ParseMultiSigContract(script []byte) ([][]byte, bool) { +// ParseMultiSigContract returns number of signatures and list of public keys +// from the verification script of the contract. +func ParseMultiSigContract(script []byte) (int, [][]byte, bool) { var nsigs, nkeys int ctx := NewContext(script) instr, param, err := ctx.Next() if err != nil { - return nil, false + return nsigs, nil, false } nsigs, ok := getNumOfThingsFromInstr(instr, param) if !ok { - return nil, false + return nsigs, nil, false } var pubs [][]byte for { instr, param, err = ctx.Next() if err != nil { - return nil, false + return nsigs, nil, false } if instr != opcode.PUSHDATA1 { break } if len(param) < 33 { - return nil, false + return nsigs, nil, false } pubs = append(pubs, param) nkeys++ if nkeys > MaxArraySize { - return nil, false + return nsigs, nil, false } } if nkeys < nsigs { - return nil, false + return nsigs, nil, false } nkeys2, ok := getNumOfThingsFromInstr(instr, param) if !ok { - return nil, false + return nsigs, nil, false } if nkeys2 != nkeys { - return nil, false + return nsigs, nil, false } instr, _, err = ctx.Next() if err != nil || instr != opcode.PUSHNULL { - return nil, false + return nsigs, nil, false } instr, param, err = ctx.Next() if err != nil || instr != opcode.SYSCALL || binary.LittleEndian.Uint32(param) != multisigInteropID { - return nil, false + return nsigs, nil, false } instr, _, err = ctx.Next() if err != nil || instr != opcode.RET || ctx.ip != len(script) { - return nil, false + return nsigs, nil, false } - return pubs, true + return nsigs, pubs, true } // IsSignatureContract checks whether the passed script is a signature check