core: add test to check GetTransactionSigners interop API

This commit is contained in:
Anna Shaleva 2022-04-27 11:58:46 +03:00
parent 8ca8a825ef
commit 1762fd9128
2 changed files with 100 additions and 5 deletions

View file

@ -1,9 +1,12 @@
package native_test package native_test
import ( import (
"fmt"
"math/big" "math/big"
"strings"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -209,3 +212,92 @@ func TestLedger_GetTransactionSigners(t *testing.T) {
ledgerInvoker.InvokeFail(t, "expected []byte of size 32", "getTransactionSigners", []byte{1, 2, 3}) ledgerInvoker.InvokeFail(t, "expected []byte of size 32", "getTransactionSigners", []byte{1, 2, 3})
}) })
} }
func TestLedger_GetTransactionSignersInteropAPI(t *testing.T) {
c := newLedgerClient(t)
e := c.Executor
ledgerInvoker := c.WithSigners(c.Committee)
// Firstly, add transaction with CalledByEntry rule-based signer scope to the chain.
tx := e.NewUnsignedTx(t, ledgerInvoker.Hash, "currentIndex")
tx.Signers = []transaction.Signer{{
Account: c.Committee.ScriptHash(),
Scopes: transaction.Rules,
Rules: []transaction.WitnessRule{
{
Action: transaction.WitnessAllow,
Condition: transaction.ConditionCalledByEntry{},
},
},
}}
neotest.AddNetworkFee(e.Chain, tx, c.Committee)
neotest.AddSystemFee(e.Chain, tx, -1)
require.NoError(t, c.Committee.SignTx(e.Chain.GetConfig().Magic, tx))
c.AddNewBlock(t, tx)
c.CheckHalt(t, tx.Hash(), stackitem.Make(e.Chain.BlockHeight()-1))
var (
hashStr string
accStr string
txHash = tx.Hash().BytesBE()
acc = c.Committee.ScriptHash().BytesBE()
)
for i := 0; i < util.Uint256Size; i++ {
hashStr += fmt.Sprintf("%#x", txHash[i])
if i != util.Uint256Size-1 {
hashStr += ", "
}
}
for i := 0; i < util.Uint160Size; i++ {
accStr += fmt.Sprintf("%#x", acc[i])
if i != util.Uint160Size-1 {
accStr += ", "
}
}
// After that ensure interop API allows to retrieve signer with CalledByEntry rule-based scope.
src := `package callledger
import (
"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/util"
)
func CallLedger(accessValue bool) int {
signers := ledger.GetTransactionSigners(interop.Hash256{` + hashStr + `})
if len(signers) != 1 {
panic("bad length")
}
s0 := signers[0]
expectedAcc := interop.Hash160{` + accStr + `}
if !util.Equals(string(s0.Account), string(expectedAcc)) {
panic("bad account")
}
if s0.Scopes != ledger.Rules {
panic("bad signer scope")
}
if len(s0.Rules) != 1 {
panic("bad rules length")
}
r0 := s0.Rules[0]
if r0.Action != ledger.WitnessAllow {
panic("bad action")
}
c0 := r0.Condition
if c0.Type != ledger.WitnessCalledByEntry {
panic("bad condition type")
}
if accessValue {
// Panic should occur here, because there's only Type inside the CalledByEntry condition.
_ = c0.Value
}
return 1
}`
ctr := neotest.CompileSource(t, c.Committee.ScriptHash(), strings.NewReader(src), &compiler.Options{
Name: "calledger_contract",
})
e.DeployContract(t, ctr, nil)
ctrInvoker := e.NewInvoker(ctr.Hash, e.Committee)
ctrInvoker.Invoke(t, 1, "callLedger", false) // Firstly, don't access CalledByEnrty Condition value => the call should be successful.
ctrInvoker.InvokeFail(t, `(PICKITEM): unhandled exception: "The value 1 is out of range."`, "callLedger", true) // Then, access the value to ensure it will panic.
}

View file

@ -107,8 +107,8 @@ func (e *Executor) SignTx(t testing.TB, tx *transaction.Transaction, sysFee int6
Scopes: transaction.Global, Scopes: transaction.Global,
}) })
} }
addNetworkFee(e.Chain, tx, signers...) AddNetworkFee(e.Chain, tx, signers...)
addSystemFee(e.Chain, tx, sysFee) AddSystemFee(e.Chain, tx, sysFee)
for _, acc := range signers { for _, acc := range signers {
require.NoError(t, acc.SignTx(e.Chain.GetConfig().Magic, tx)) require.NoError(t, acc.SignTx(e.Chain.GetConfig().Magic, tx))
@ -276,12 +276,14 @@ func NewDeployTxBy(t testing.TB, bc blockchainer.Blockchainer, signer Signer, c
Account: signer.ScriptHash(), Account: signer.ScriptHash(),
Scopes: transaction.Global, Scopes: transaction.Global,
}} }}
addNetworkFee(bc, tx, signer) AddNetworkFee(bc, tx, signer)
require.NoError(t, signer.SignTx(netmode.UnitTestNet, tx)) require.NoError(t, signer.SignTx(netmode.UnitTestNet, tx))
return tx return tx
} }
func addSystemFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, sysFee int64) { // AddSystemFee adds system fee to the transaction. If negative value specified,
// then system fee is defined by test invocation.
func AddSystemFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, sysFee int64) {
if sysFee >= 0 { if sysFee >= 0 {
tx.SystemFee = sysFee tx.SystemFee = sysFee
return return
@ -290,7 +292,8 @@ func addSystemFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, sys
tx.SystemFee = v.GasConsumed() tx.SystemFee = v.GasConsumed()
} }
func addNetworkFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, signers ...Signer) { // AddNetworkFee adds network fee to the transaction.
func AddNetworkFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, signers ...Signer) {
baseFee := bc.GetBaseExecFee() baseFee := bc.GetBaseExecFee()
size := io.GetVarSize(tx) size := io.GetVarSize(tx)
for _, sgr := range signers { for _, sgr := range signers {