2021-09-10 17:29:32 +00:00
|
|
|
package event
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"testing"
|
|
|
|
|
2021-09-13 09:02:32 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
|
|
|
|
2021-09-10 17:29:32 +00:00
|
|
|
"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())
|
2021-09-13 09:02:32 +00:00
|
|
|
|
|
|
|
// 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)
|
2021-09-10 17:29:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|