nativetest: migrate Ledger contract tests to neotest
This commit is contained in:
parent
bbe92c21ea
commit
4e7435081f
2 changed files with 147 additions and 174 deletions
147
pkg/core/native/native_test/ledger_test.go
Normal file
147
pkg/core/native/native_test/ledger_test.go
Normal file
|
@ -0,0 +1,147 @@
|
|||
package native_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/neotest/chain"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func newLedgerClient(t *testing.T) *neotest.ContractInvoker {
|
||||
bc, acc := chain.NewSingleWithCustomConfig(t, func(cfg *config.ProtocolConfiguration) {
|
||||
cfg.MaxTraceableBlocks = 10 // reduce number of traceable blocks for Ledger tests
|
||||
})
|
||||
e := neotest.NewExecutor(t, bc, acc, acc)
|
||||
|
||||
return e.CommitteeInvoker(e.NativeHash(t, nativenames.Ledger))
|
||||
}
|
||||
|
||||
func TestLedger_GetTransactionHeight(t *testing.T) {
|
||||
c := newLedgerClient(t)
|
||||
e := c.Executor
|
||||
ledgerInvoker := c.WithSigners(c.Committee)
|
||||
|
||||
height := 13
|
||||
e.GenerateNewBlocks(t, height-1)
|
||||
hash := e.InvokeScript(t, []byte{byte(opcode.RET)}, []neotest.Signer{c.Committee})
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, height, "getTransactionHeight", hash)
|
||||
})
|
||||
t.Run("unknown transaction", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, -1, "getTransactionHeight", util.Uint256{1, 2, 3})
|
||||
})
|
||||
t.Run("not a hash", func(t *testing.T) {
|
||||
ledgerInvoker.InvokeFail(t, "expected []byte of size 32", "getTransactionHeight", []byte{1, 2, 3})
|
||||
})
|
||||
}
|
||||
|
||||
func TestLedger_GetTransaction(t *testing.T) {
|
||||
c := newLedgerClient(t)
|
||||
e := c.Executor
|
||||
ledgerInvoker := c.WithSigners(c.Committee)
|
||||
|
||||
hash := e.InvokeScript(t, []byte{byte(opcode.RET)}, []neotest.Signer{c.Committee})
|
||||
tx, _ := e.GetTransaction(t, hash)
|
||||
|
||||
t.Run("success", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, []stackitem.Item{
|
||||
stackitem.NewByteArray(tx.Hash().BytesBE()),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(tx.Version))),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(tx.Nonce))),
|
||||
stackitem.NewByteArray(tx.Sender().BytesBE()),
|
||||
stackitem.NewBigInteger(big.NewInt(tx.SystemFee)),
|
||||
stackitem.NewBigInteger(big.NewInt(tx.NetworkFee)),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(tx.ValidUntilBlock))),
|
||||
stackitem.NewByteArray(tx.Script),
|
||||
}, "getTransaction", tx.Hash())
|
||||
})
|
||||
t.Run("isn't traceable", func(t *testing.T) {
|
||||
// Add more blocks so that tx becomes untraceable.
|
||||
e.GenerateNewBlocks(t, int(e.Chain.GetConfig().MaxTraceableBlocks))
|
||||
ledgerInvoker.Invoke(t, stackitem.Null{}, "getTransaction", tx.Hash())
|
||||
})
|
||||
t.Run("bad hash", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, stackitem.Null{}, "getTransaction", util.Uint256{})
|
||||
})
|
||||
}
|
||||
|
||||
func TestLedger_GetTransactionFromBlock(t *testing.T) {
|
||||
c := newLedgerClient(t)
|
||||
e := c.Executor
|
||||
ledgerInvoker := c.WithSigners(c.Committee)
|
||||
|
||||
ledgerInvoker.Invoke(t, e.Chain.BlockHeight(), "currentIndex") // Adds a block.
|
||||
b := e.GetBlockByIndex(t, int(e.Chain.BlockHeight()))
|
||||
|
||||
check := func(t *testing.T, stack []stackitem.Item) {
|
||||
require.Equal(t, 1, len(stack))
|
||||
actual, ok := stack[0].Value().([]stackitem.Item)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, b.Transactions[0].Hash().BytesBE(), actual[0].Value().([]byte))
|
||||
}
|
||||
t.Run("good, by hash", func(t *testing.T) {
|
||||
ledgerInvoker.InvokeAndCheck(t, check, "getTransactionFromBlock", b.Hash(), int64(0))
|
||||
})
|
||||
t.Run("good, by index", func(t *testing.T) {
|
||||
ledgerInvoker.InvokeAndCheck(t, check, "getTransactionFromBlock", int64(b.Index), int64(0))
|
||||
})
|
||||
t.Run("bad transaction index", func(t *testing.T) {
|
||||
ledgerInvoker.InvokeFail(t, "", "getTransactionFromBlock", b.Hash(), int64(1))
|
||||
})
|
||||
t.Run("bad block hash (>int64)", func(t *testing.T) {
|
||||
ledgerInvoker.InvokeFail(t, "", "getTransactionFromBlock", b.Hash().BytesBE()[:10], int64(0))
|
||||
})
|
||||
t.Run("invalid block hash (int64)", func(t *testing.T) {
|
||||
ledgerInvoker.InvokeFail(t, "", "getTransactionFromBlock", b.Hash().BytesBE()[:6], int64(0))
|
||||
})
|
||||
t.Run("unknown block hash", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, stackitem.Null{}, "getTransactionFromBlock", b.Hash().BytesLE(), int64(0))
|
||||
})
|
||||
t.Run("isn't traceable", func(t *testing.T) {
|
||||
e.GenerateNewBlocks(t, int(e.Chain.GetConfig().MaxTraceableBlocks))
|
||||
ledgerInvoker.Invoke(t, stackitem.Null{}, "getTransactionFromBlock", b.Hash(), int64(0))
|
||||
})
|
||||
}
|
||||
|
||||
func TestLedger_GetBlock(t *testing.T) {
|
||||
c := newLedgerClient(t)
|
||||
e := c.Executor
|
||||
ledgerInvoker := c.WithSigners(c.Committee)
|
||||
|
||||
ledgerInvoker.Invoke(t, e.Chain.GetHeaderHash(int(e.Chain.BlockHeight())).BytesBE(), "currentHash") // Adds a block.
|
||||
b := e.GetBlockByIndex(t, int(e.Chain.BlockHeight()))
|
||||
|
||||
expected := []stackitem.Item{
|
||||
stackitem.NewByteArray(b.Hash().BytesBE()),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(b.Version))),
|
||||
stackitem.NewByteArray(b.PrevHash.BytesBE()),
|
||||
stackitem.NewByteArray(b.MerkleRoot.BytesBE()),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(b.Timestamp))),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(b.Nonce))),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(b.Index))),
|
||||
stackitem.NewByteArray(b.NextConsensus.BytesBE()),
|
||||
stackitem.NewBigInteger(big.NewInt(int64(len(b.Transactions)))),
|
||||
}
|
||||
t.Run("good, by hash", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, expected, "getBlock", b.Hash())
|
||||
})
|
||||
t.Run("good, by index", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, expected, "getBlock", int64(b.Index))
|
||||
})
|
||||
t.Run("bad hash", func(t *testing.T) {
|
||||
ledgerInvoker.Invoke(t, stackitem.Null{}, "getBlock", b.Hash().BytesLE())
|
||||
})
|
||||
t.Run("isn't traceable", func(t *testing.T) {
|
||||
e.GenerateNewBlocks(t, int(e.Chain.GetConfig().MaxTraceableBlocks))
|
||||
ledgerInvoker.Invoke(t, stackitem.Null{}, "getBlock", b.Hash())
|
||||
})
|
||||
}
|
|
@ -1,174 +0,0 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLedgerGetTransactionHeight(t *testing.T) {
|
||||
_, tx, _, chain := createVMAndTX(t)
|
||||
|
||||
ledger := chain.contracts.ByName(nativenames.Ledger).Metadata().Hash
|
||||
|
||||
for i := 0; i < 13; i++ {
|
||||
require.NoError(t, chain.AddBlock(chain.newBlock()))
|
||||
}
|
||||
require.NoError(t, chain.dao.StoreAsTransaction(tx, 13, nil, nil))
|
||||
t.Run("good", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionHeight", tx.Hash().BytesBE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Make(13))
|
||||
})
|
||||
t.Run("bad", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionHeight", tx.Hash().BytesLE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Make(-1))
|
||||
})
|
||||
t.Run("not a hash", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionHeight", []byte{1})
|
||||
require.NoError(t, err)
|
||||
checkFAULTState(t, res)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLedgerGetTransaction(t *testing.T) {
|
||||
_, tx, _, chain := createVMAndTX(t)
|
||||
ledger := chain.contracts.ByName(nativenames.Ledger).Metadata().Hash
|
||||
|
||||
t.Run("success", func(t *testing.T) {
|
||||
require.NoError(t, chain.dao.StoreAsTransaction(tx, 0, nil, nil))
|
||||
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransaction", tx.Hash().BytesBE())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, vm.HaltState, res.VMState, res.FaultException)
|
||||
require.Equal(t, 1, len(res.Stack))
|
||||
value := res.Stack[0].Value()
|
||||
|
||||
actual, ok := value.([]stackitem.Item)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, 8, len(actual))
|
||||
require.Equal(t, tx.Hash().BytesBE(), actual[0].Value().([]byte))
|
||||
require.Equal(t, int64(tx.Version), actual[1].Value().(*big.Int).Int64())
|
||||
require.Equal(t, int64(tx.Nonce), actual[2].Value().(*big.Int).Int64())
|
||||
require.Equal(t, tx.Sender().BytesBE(), actual[3].Value().([]byte))
|
||||
require.Equal(t, int64(tx.SystemFee), actual[4].Value().(*big.Int).Int64())
|
||||
require.Equal(t, int64(tx.NetworkFee), actual[5].Value().(*big.Int).Int64())
|
||||
require.Equal(t, int64(tx.ValidUntilBlock), actual[6].Value().(*big.Int).Int64())
|
||||
require.Equal(t, tx.Script, actual[7].Value().([]byte))
|
||||
})
|
||||
|
||||
t.Run("isn't traceable", func(t *testing.T) {
|
||||
require.NoError(t, chain.dao.StoreAsTransaction(tx, 2, nil, nil)) // block 1 is added above
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransaction", tx.Hash().BytesBE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Null{})
|
||||
})
|
||||
t.Run("bad hash", func(t *testing.T) {
|
||||
require.NoError(t, chain.dao.StoreAsTransaction(tx, 0, nil, nil))
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransaction", tx.Hash().BytesLE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Null{})
|
||||
})
|
||||
}
|
||||
|
||||
func TestLedgerGetTransactionFromBlock(t *testing.T) {
|
||||
chain := newTestChain(t)
|
||||
ledger := chain.contracts.ByName(nativenames.Ledger).Metadata().Hash
|
||||
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "currentIndex") // adds a block
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Make(0))
|
||||
bhash := chain.GetHeaderHash(1)
|
||||
b, err := chain.GetBlock(bhash)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("success", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionFromBlock", bhash.BytesBE(), int64(0))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, vm.HaltState, res.VMState, res.FaultException)
|
||||
require.Equal(t, 1, len(res.Stack))
|
||||
value := res.Stack[0].Value()
|
||||
|
||||
actual, ok := value.([]stackitem.Item)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, b.Transactions[0].Hash().BytesBE(), actual[0].Value().([]byte))
|
||||
})
|
||||
t.Run("bad transaction index", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionFromBlock", bhash.BytesBE(), int64(1))
|
||||
require.NoError(t, err)
|
||||
checkFAULTState(t, res)
|
||||
})
|
||||
t.Run("invalid block hash (>int64)", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionFromBlock", bhash.BytesBE()[:10], int64(0))
|
||||
require.NoError(t, err)
|
||||
checkFAULTState(t, res)
|
||||
})
|
||||
t.Run("invalid block hash (int64)", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionFromBlock", bhash.BytesBE()[:6], int64(0))
|
||||
require.NoError(t, err)
|
||||
checkFAULTState(t, res)
|
||||
})
|
||||
t.Run("bad block hash", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionFromBlock", bhash.BytesLE(), int64(0))
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Null{})
|
||||
})
|
||||
t.Run("isn't traceable", func(t *testing.T) {
|
||||
b.Index = chain.BlockHeight() + 1
|
||||
require.NoError(t, chain.dao.StoreAsBlock(b, nil, nil, nil))
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getTransactionFromBlock", bhash.BytesBE(), int64(0))
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Null{})
|
||||
})
|
||||
}
|
||||
|
||||
func TestLedgerGetBlock(t *testing.T) {
|
||||
chain := newTestChain(t)
|
||||
ledger := chain.contracts.ByName(nativenames.Ledger).Metadata().Hash
|
||||
|
||||
bhash := chain.GetHeaderHash(0)
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "currentHash") // adds a block
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Make(bhash.BytesBE()))
|
||||
bhash = chain.GetHeaderHash(1)
|
||||
b, err := chain.GetBlock(bhash)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("success", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getBlock", bhash.BytesBE())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, vm.HaltState, res.VMState, res.FaultException)
|
||||
require.Equal(t, 1, len(res.Stack))
|
||||
value := res.Stack[0].Value()
|
||||
|
||||
actual, ok := value.([]stackitem.Item)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, 9, len(actual))
|
||||
require.Equal(t, b.Hash().BytesBE(), actual[0].Value().([]byte))
|
||||
require.Equal(t, int64(b.Version), actual[1].Value().(*big.Int).Int64())
|
||||
require.Equal(t, b.PrevHash.BytesBE(), actual[2].Value().([]byte))
|
||||
require.Equal(t, b.MerkleRoot.BytesBE(), actual[3].Value().([]byte))
|
||||
require.Equal(t, int64(b.Timestamp), actual[4].Value().(*big.Int).Int64())
|
||||
require.Equal(t, int64(b.Nonce), actual[5].Value().(*big.Int).Int64())
|
||||
require.Equal(t, int64(b.Index), actual[6].Value().(*big.Int).Int64())
|
||||
require.Equal(t, b.NextConsensus.BytesBE(), actual[7].Value().([]byte))
|
||||
require.Equal(t, int64(len(b.Transactions)), actual[8].Value().(*big.Int).Int64())
|
||||
})
|
||||
t.Run("bad hash", func(t *testing.T) {
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getBlock", bhash.BytesLE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Null{})
|
||||
})
|
||||
t.Run("isn't traceable", func(t *testing.T) {
|
||||
b.Index = chain.BlockHeight() + 1
|
||||
require.NoError(t, chain.dao.StoreAsBlock(b, nil, nil, nil))
|
||||
res, err := invokeContractMethod(chain, 100000000, ledger, "getBlock", bhash.BytesBE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Null{})
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue