2020-02-17 11:54:53 +00:00
package request
import (
"encoding/hex"
2021-10-28 11:10:18 +00:00
"fmt"
2022-02-09 12:13:15 +00:00
"math/big"
2020-02-17 11:54:53 +00:00
"testing"
2020-08-27 08:44:40 +00:00
"github.com/nspcc-dev/neo-go/pkg/io"
2020-03-03 14:21:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/util"
2020-08-27 08:44:40 +00:00
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
2020-02-17 11:54:53 +00:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestInvocationScriptCreationGood ( t * testing . T ) {
2021-10-28 11:10:18 +00:00
p := Param { RawMessage : [ ] byte ( ` "50befd26fdf6e4d957c11e078b24ebce6291456f" ` ) }
2020-02-17 11:54:53 +00:00
contract , err := p . GetUint160FromHex ( )
require . Nil ( t , err )
var paramScripts = [ ] struct {
ps Params
script string
} { {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "transfer" ` ) } } ,
2021-10-16 18:09:29 +00:00
script : "c21f0c087472616e736665720c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` 42 ` ) } } ,
2021-10-16 18:09:29 +00:00
script : "c21f0c0234320c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "10c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "ByteString", "value": "AwEtR+diEK7HO+Oas9GG4KQP6Nhr+j1Pq/2le6E7iPlq"}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "0c2103012d47e76210aec73be39ab3d186e0a40fe8d86bfa3d4fabfda57ba13b88f96a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Signature", "value": "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "String", "value": "50befd26fdf6e4d957c11e078b24ebce6291456f"}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Hash160", "value": "50befd26fdf6e4d957c11e078b24ebce6291456f"}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Hash256", "value": "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "PublicKey", "value": "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Integer", "value": 42}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "002a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Integer", "value": "42"}] ` ) } } , // C# code doesn't use strict type assertions for JSON-ised params
script : "002a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
} , {
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Integer", "value": true}] ` ) } } , // C# code doesn't use strict type assertions for JSON-ised params
script : "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
} , {
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Boolean", "value": true}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} , {
2021-10-28 11:10:18 +00:00
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Boolean", "value": false}] ` ) } } ,
2020-12-29 10:44:07 +00:00
script : "1011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2021-10-28 11:10:18 +00:00
} , {
ps : Params { { RawMessage : [ ] byte ( ` "a" ` ) } , { RawMessage : [ ] byte ( ` [ { "type": "Boolean", "value": "blah"}] ` ) } } , // C# code doesn't use strict type assertions for JSON-ised params
script : "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52" ,
2020-02-17 11:54:53 +00:00
} }
2021-10-28 11:10:18 +00:00
for i , ps := range paramScripts {
method , err := ps . ps [ 0 ] . GetString ( )
require . NoError ( t , err , fmt . Sprintf ( "testcase #%d" , i ) )
2021-11-20 16:25:42 +00:00
var p * Param
if len ( ps . ps ) > 1 {
p = & ps . ps [ 1 ]
}
script , err := CreateFunctionInvocationScript ( contract , method , p )
2020-02-17 11:54:53 +00:00
assert . Nil ( t , err )
2021-10-28 11:10:18 +00:00
assert . Equal ( t , ps . script , hex . EncodeToString ( script ) , fmt . Sprintf ( "testcase #%d" , i ) )
2020-02-17 11:54:53 +00:00
}
}
func TestInvocationScriptCreationBad ( t * testing . T ) {
contract := util . Uint160 { }
2021-11-20 16:25:42 +00:00
var testParams = [ ] Param {
{ RawMessage : [ ] byte ( ` true ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "ByteArray", "value": "qwerty"}] ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "Signature", "value": "qwerty"}] ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "Hash160", "value": "qwerty"}] ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "Hash256", "value": "qwerty"}] ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "PublicKey", "value": 42}] ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "PublicKey", "value": "qwerty"}] ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "Integer", "value": "123q"}] ` ) } ,
{ RawMessage : [ ] byte ( ` [ { "type": "Unknown"}] ` ) } ,
2020-02-17 11:54:53 +00:00
}
2021-10-28 11:10:18 +00:00
for i , ps := range testParams {
2021-11-20 16:25:42 +00:00
_ , err := CreateFunctionInvocationScript ( contract , "" , & ps )
2021-10-28 11:10:18 +00:00
assert . NotNil ( t , err , fmt . Sprintf ( "testcase #%d" , i ) )
2020-02-17 11:54:53 +00:00
}
}
2020-08-27 08:44:40 +00:00
func TestExpandArrayIntoScript ( t * testing . T ) {
2022-02-09 12:13:15 +00:00
bi := new ( big . Int ) . Lsh ( big . NewInt ( 1 ) , 254 )
rawInt := make ( [ ] byte , 32 )
rawInt [ 31 ] = 0x40
2020-08-27 08:44:40 +00:00
testCases := [ ] struct {
Input [ ] Param
Expected [ ] byte
} {
{
2021-10-28 11:10:18 +00:00
Input : [ ] Param { { RawMessage : [ ] byte ( ` { "type": "String", "value": "a"} ` ) } } ,
2020-08-27 08:44:40 +00:00
Expected : [ ] byte { byte ( opcode . PUSHDATA1 ) , 1 , byte ( 'a' ) } ,
} ,
{
2021-10-28 11:10:18 +00:00
Input : [ ] Param { { RawMessage : [ ] byte ( ` { "type": "Array", "value": [ { "type": "String", "value": "a"}]} ` ) } } ,
2020-08-27 08:44:40 +00:00
Expected : [ ] byte { byte ( opcode . PUSHDATA1 ) , 1 , byte ( 'a' ) , byte ( opcode . PUSH1 ) , byte ( opcode . PACK ) } ,
} ,
2022-02-09 12:13:15 +00:00
{
Input : [ ] Param { { RawMessage : [ ] byte ( ` { "type": "Integer", "value": " ` + bi . String ( ) + ` "} ` ) } } ,
Expected : append ( [ ] byte { byte ( opcode . PUSHINT256 ) } , rawInt ... ) ,
} ,
2020-08-27 08:44:40 +00:00
}
for _ , c := range testCases {
script := io . NewBufBinWriter ( )
2021-03-10 14:43:52 +00:00
err := ExpandArrayIntoScript ( script . BinWriter , c . Input )
2020-08-27 08:44:40 +00:00
require . NoError ( t , err )
require . Equal ( t , c . Expected , script . Bytes ( ) )
}
errorCases := [ ] [ ] Param {
{
2021-10-28 11:10:18 +00:00
{ RawMessage : [ ] byte ( ` { "type": "Array", "value": "a"} ` ) } ,
2020-08-27 08:44:40 +00:00
} ,
{
2021-10-28 11:10:18 +00:00
{ RawMessage : [ ] byte ( ` { "type": "Array", "value": null} ` ) } ,
2020-08-27 08:44:40 +00:00
} ,
2022-02-09 12:38:22 +00:00
{
{ RawMessage : [ ] byte ( ` { "type": "Integer", "value": " ` +
new ( big . Int ) . Lsh ( big . NewInt ( 1 ) , 255 ) . String ( ) + ` "} ` ) } ,
} ,
2020-08-27 08:44:40 +00:00
}
for _ , c := range errorCases {
script := io . NewBufBinWriter ( )
2021-03-10 14:43:52 +00:00
err := ExpandArrayIntoScript ( script . BinWriter , c )
2020-08-27 08:44:40 +00:00
require . Error ( t , err )
}
}