frostfs-node/pkg/morph/event/notary_preparator_test.go
Pavel Karpy f0beb4abc9 [#825] event/notaryPreparator: Add args checking unit test
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
2021-09-15 18:07:50 +03:00

185 lines
4 KiB
Go

package event
import (
"encoding/binary"
"testing"
"github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/network/payload"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/stretchr/testify/require"
)
var (
alphaKeys keys.PublicKeys
dummyInvocationScript = append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...)
contractSysCall = make([]byte, 4)
scriptHash util.Uint160
)
func init() {
privat, _ := keys.NewPrivateKey()
pub := privat.PublicKey()
alphaKeys = keys.PublicKeys{pub}
binary.LittleEndian.PutUint32(contractSysCall, interopnames.ToID([]byte(interopnames.SystemContractCall)))
scriptHash, _ = util.Uint160DecodeStringLE("21fce15191428e9c2f0e8d0329ff6d3dd14882de")
}
type blockCounter struct {
epoch uint32
err error
}
func (b blockCounter) BlockCount() (res uint32, err error) {
return b.epoch, b.err
}
func TestPrepare_CorrectNR(t *testing.T) {
tests := []struct {
hash util.Uint160
method string
args []interface{}
}{
{
scriptHash,
"test1",
nil,
},
{
scriptHash,
"test2",
[]interface{}{
int64(4),
"test",
[]interface{}{
int64(4),
false,
true,
},
},
},
}
preparator := notaryPreparator(
PreparatorPrm{
alphaKeysSource(),
blockCounter{100, nil},
},
)
for _, test := range tests {
nr := correctNR(script(test.hash, test.method, test.args...))
event, err := preparator.Prepare(nr)
require.NoError(t, err)
require.Equal(t, test.method, event.Type().String())
require.Equal(t, test.hash.StringLE(), event.ScriptHash().StringLE())
// check args parsing
bw := io.NewBufBinWriter()
emit.Array(bw.BinWriter, test.args...)
ctx := vm.NewContext(bw.Bytes())
opCode, param, err := ctx.Next()
require.NoError(t, err)
for _, opGot := range event.Params() {
require.Equal(t, opCode, opGot.code)
require.Equal(t, param, opGot.param)
opCode, param, err = ctx.Next()
require.NoError(t, err)
}
_, _, err = ctx.Next() // PACK opcode
require.NoError(t, err)
_, _, err = ctx.Next() // packing len opcode
require.NoError(t, err)
opCode, _, err = ctx.Next()
require.NoError(t, err)
require.Equal(t, opcode.RET, opCode)
}
}
func alphaKeysSource() client.AlphabetKeys {
return func() (keys.PublicKeys, error) {
return alphaKeys, nil
}
}
func script(hash util.Uint160, method string, args ...interface{}) []byte {
bw := io.NewBufBinWriter()
if len(args) > 0 {
emit.AppCall(bw.BinWriter, hash, method, callflag.All, args)
} else {
emit.AppCallNoArgs(bw.BinWriter, hash, method, callflag.All)
}
return bw.Bytes()
}
func correctNR(script []byte) *payload.P2PNotaryRequest {
alphaVerificationScript, _ := smartcontract.CreateMultiSigRedeemScript(len(alphaKeys)*2/3+1, alphaKeys)
return &payload.P2PNotaryRequest{
MainTransaction: &transaction.Transaction{
Signers: []transaction.Signer{
{},
{
Account: hash.Hash160(alphaVerificationScript),
},
{},
},
Scripts: []transaction.Witness{
{},
{
InvocationScript: dummyInvocationScript,
VerificationScript: alphaVerificationScript,
},
{
InvocationScript: dummyInvocationScript,
},
},
Attributes: []transaction.Attribute{
{
Value: &transaction.NotaryAssisted{
NKeys: uint8(len(alphaKeys)),
},
},
},
Script: script,
},
FallbackTransaction: &transaction.Transaction{
Attributes: []transaction.Attribute{
{},
{
Type: transaction.NotValidBeforeT,
Value: &transaction.NotValidBefore{
Height: 1000,
},
},
{},
},
},
}
}