From 4df5d370c5a7cd008a89116a3dfee1f74dcb3d10 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Thu, 11 Nov 2021 20:00:40 +0300 Subject: [PATCH 1/3] neotest: export nonce() method Sometimes user needs to construct transaction by itself, so it's better to unify nonce sources for auto-generated and manually-generated transactions to avoid nonce collisions in tests. --- pkg/neotest/account.go | 3 ++- pkg/neotest/basic.go | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/neotest/account.go b/pkg/neotest/account.go index 00c95a7a0..d03db8d33 100644 --- a/pkg/neotest/account.go +++ b/pkg/neotest/account.go @@ -2,7 +2,8 @@ package neotest var _nonce uint32 -func nonce() uint32 { +// Nonce returns unique number that can be used as nonce for new transactions. +func Nonce() uint32 { _nonce++ return _nonce } diff --git a/pkg/neotest/basic.go b/pkg/neotest/basic.go index 67c0ac87b..a572fab53 100644 --- a/pkg/neotest/basic.go +++ b/pkg/neotest/basic.go @@ -69,7 +69,7 @@ func (e *Executor) NewUnsignedTx(t *testing.T, hash util.Uint160, method string, script := w.Bytes() tx := transaction.New(script, 0) - tx.Nonce = nonce() + tx.Nonce = Nonce() tx.ValidUntilBlock = e.Chain.BlockHeight() + 1 return tx } @@ -157,7 +157,7 @@ func (e *Executor) NewDeployTx(t *testing.T, bc blockchainer.Blockchainer, c *Co require.NoError(t, buf.Err) tx := transaction.New(buf.Bytes(), 100*native.GASFactor) - tx.Nonce = nonce() + tx.Nonce = Nonce() tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.Signers = []transaction.Signer{{ Account: e.Committee.ScriptHash(), From 4057e635af6e772c15f38bdbb20db32f1d46eb06 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Tue, 16 Nov 2021 17:40:01 +0300 Subject: [PATCH 2/3] neotest: add API to check notification event --- pkg/neotest/basic.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/neotest/basic.go b/pkg/neotest/basic.go index a572fab53..854a907e2 100644 --- a/pkg/neotest/basic.go +++ b/pkg/neotest/basic.go @@ -2,6 +2,7 @@ package neotest import ( "encoding/json" + "fmt" "strings" "testing" @@ -144,6 +145,19 @@ func (e *Executor) CheckFault(t *testing.T, h util.Uint256, s string) { "expected: %s, got: %s", s, aer[0].FaultException) } +// CheckTxNotificationEvent checks that specified event was emitted at the specified position +// during transaction script execution. Negative index corresponds to backwards enumeration. +func (e *Executor) CheckTxNotificationEvent(t *testing.T, h util.Uint256, index int, expected state.NotificationEvent) { + aer, err := e.Chain.GetAppExecResults(h, trigger.Application) + require.NoError(t, err) + l := len(aer[0].Events) + if index < 0 { + index = l + index + } + require.True(t, 0 <= index && index < l, fmt.Errorf("notification index is out of range: want %d, len is %d", index, l)) + require.Equal(t, expected, aer[0].Events[index]) +} + // NewDeployTx returns new deployment tx for contract signed by committee. func (e *Executor) NewDeployTx(t *testing.T, bc blockchainer.Blockchainer, c *Contract, data interface{}) *transaction.Transaction { rawManifest, err := json.Marshal(c.Manifest) From 1194361826ab78ce8eb2ec899d12cbe188b0465c Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Tue, 16 Nov 2021 17:35:39 +0300 Subject: [PATCH 3/3] neotest: check deployed contract hash --- .../nft-nd-nns/tests/nonnative_name_service_test.go | 5 +---- pkg/neotest/basic.go | 13 ++++++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/nft-nd-nns/tests/nonnative_name_service_test.go b/examples/nft-nd-nns/tests/nonnative_name_service_test.go index 40840981a..ecd602786 100644 --- a/examples/nft-nd-nns/tests/nonnative_name_service_test.go +++ b/examples/nft-nd-nns/tests/nonnative_name_service_test.go @@ -20,10 +20,7 @@ func newNSClient(t *testing.T) *neotest.ContractInvoker { c := neotest.CompileFile(t, e.CommitteeHash, "..", "../nns.yml") e.DeployContract(t, c, nil) - h, err := e.Chain.GetContractScriptHash(1) - require.NoError(t, err) - require.Equal(t, c.Hash, h) - return e.CommitteeInvoker(h) + return e.CommitteeInvoker(c.Hash) } func TestNameService_Price(t *testing.T) { diff --git a/pkg/neotest/basic.go b/pkg/neotest/basic.go index 854a907e2..422c967be 100644 --- a/pkg/neotest/basic.go +++ b/pkg/neotest/basic.go @@ -114,13 +114,24 @@ func (e *Executor) NewAccount(t *testing.T) Signer { return NewSingleSigner(acc) } -// DeployContract compiles and deploys contract to bc. +// DeployContract compiles and deploys contract to bc. It also checks that +// precalculated contract hash matches the actual one. // data is an optional argument to `_deploy`. // Returns hash of the deploy transaction. func (e *Executor) DeployContract(t *testing.T, c *Contract, data interface{}) util.Uint256 { tx := e.NewDeployTx(t, e.Chain, c, data) e.AddNewBlock(t, tx) e.CheckHalt(t, tx.Hash()) + + // Check that precalculated hash matches the real one. + e.CheckTxNotificationEvent(t, tx.Hash(), -1, state.NotificationEvent{ + ScriptHash: e.NativeHash(t, nativenames.Management), + Name: "Deploy", + Item: stackitem.NewArray([]stackitem.Item{ + stackitem.NewByteArray(c.Hash.BytesBE()), + }), + }) + return tx.Hash() }