2022-08-23 19:00:23 +00:00
package notary
import (
"errors"
2023-05-15 15:04:32 +00:00
"math"
2022-08-23 19:00:23 +00:00
"math/big"
2023-05-15 15:04:32 +00:00
"strings"
2022-08-23 19:00:23 +00:00
"testing"
2023-05-15 15:04:32 +00:00
"github.com/nspcc-dev/neo-go/internal/testserdes"
2022-08-23 19:00:23 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require"
)
type testAct struct {
err error
res * result . Invoke
tx * transaction . Transaction
txh util . Uint256
vub uint32
}
2023-04-03 10:34:24 +00:00
func ( t * testAct ) Call ( contract util . Uint160 , operation string , params ... any ) ( * result . Invoke , error ) {
2022-08-23 19:00:23 +00:00
return t . res , t . err
}
func ( t * testAct ) MakeRun ( script [ ] byte ) ( * transaction . Transaction , error ) {
return t . tx , t . err
}
func ( t * testAct ) MakeUnsignedRun ( script [ ] byte , attrs [ ] transaction . Attribute ) ( * transaction . Transaction , error ) {
return t . tx , t . err
}
func ( t * testAct ) SendRun ( script [ ] byte ) ( util . Uint256 , uint32 , error ) {
return t . txh , t . vub , t . err
}
2023-04-03 10:34:24 +00:00
func ( t * testAct ) MakeCall ( contract util . Uint160 , method string , params ... any ) ( * transaction . Transaction , error ) {
2022-08-23 19:00:23 +00:00
return t . tx , t . err
}
2023-04-03 10:34:24 +00:00
func ( t * testAct ) MakeUnsignedCall ( contract util . Uint160 , method string , attrs [ ] transaction . Attribute , params ... any ) ( * transaction . Transaction , error ) {
2022-08-23 19:00:23 +00:00
return t . tx , t . err
}
2023-04-03 10:34:24 +00:00
func ( t * testAct ) SendCall ( contract util . Uint160 , method string , params ... any ) ( util . Uint256 , uint32 , error ) {
2022-08-23 19:00:23 +00:00
return t . txh , t . vub , t . err
}
func TestBalanceOf ( t * testing . T ) {
ta := & testAct { }
ntr := NewReader ( ta )
ta . err = errors . New ( "" )
_ , err := ntr . BalanceOf ( util . Uint160 { } )
require . Error ( t , err )
ta . err = nil
ta . res = & result . Invoke {
State : "HALT" ,
Stack : [ ] stackitem . Item {
stackitem . Make ( 42 ) ,
} ,
}
res , err := ntr . BalanceOf ( util . Uint160 { } )
require . NoError ( t , err )
require . Equal ( t , big . NewInt ( 42 ) , res )
}
func TestUint32Getters ( t * testing . T ) {
ta := & testAct { }
ntr := NewReader ( ta )
for name , fun := range map [ string ] func ( ) ( uint32 , error ) {
"ExpirationOf" : func ( ) ( uint32 , error ) {
return ntr . ExpirationOf ( util . Uint160 { 1 , 2 , 3 } )
} ,
"GetMaxNotValidBeforeDelta" : ntr . GetMaxNotValidBeforeDelta ,
} {
t . Run ( name , func ( t * testing . T ) {
ta . err = errors . New ( "" )
_ , err := fun ( )
require . Error ( t , err )
ta . err = nil
ta . res = & result . Invoke {
State : "HALT" ,
Stack : [ ] stackitem . Item {
stackitem . Make ( 42 ) ,
} ,
}
res , err := fun ( )
require . NoError ( t , err )
require . Equal ( t , uint32 ( 42 ) , res )
ta . res = & result . Invoke {
State : "HALT" ,
Stack : [ ] stackitem . Item {
stackitem . Make ( - 1 ) ,
} ,
}
_ , err = fun ( )
require . Error ( t , err )
} )
}
}
func TestGetNotaryServiceFeePerKey ( t * testing . T ) {
ta := & testAct { }
ntr := NewReader ( ta )
ta . err = errors . New ( "" )
_ , err := ntr . GetNotaryServiceFeePerKey ( )
require . Error ( t , err )
ta . err = nil
ta . res = & result . Invoke {
State : "HALT" ,
Stack : [ ] stackitem . Item {
stackitem . Make ( 42 ) ,
} ,
}
res , err := ntr . GetNotaryServiceFeePerKey ( )
require . NoError ( t , err )
require . Equal ( t , int64 ( 42 ) , res )
}
func TestTxSenders ( t * testing . T ) {
ta := new ( testAct )
ntr := New ( ta )
for name , fun := range map [ string ] func ( ) ( util . Uint256 , uint32 , error ) {
"LockDepositUntil" : func ( ) ( util . Uint256 , uint32 , error ) {
return ntr . LockDepositUntil ( util . Uint160 { 1 , 2 , 3 } , 100500 )
} ,
"SetMaxNotValidBeforeDelta" : func ( ) ( util . Uint256 , uint32 , error ) {
return ntr . SetMaxNotValidBeforeDelta ( 42 )
} ,
"SetNotaryServiceFeePerKey" : func ( ) ( util . Uint256 , uint32 , error ) {
return ntr . SetNotaryServiceFeePerKey ( 100500 )
} ,
"Withdraw" : func ( ) ( util . Uint256 , uint32 , error ) {
return ntr . Withdraw ( util . Uint160 { 1 , 2 , 3 } , util . Uint160 { 3 , 2 , 1 } )
} ,
} {
t . Run ( name , func ( t * testing . T ) {
ta . err = errors . New ( "" )
_ , _ , err := fun ( )
require . Error ( t , err )
ta . err = nil
ta . txh = util . Uint256 { 1 , 2 , 3 }
ta . vub = 42
h , vub , err := fun ( )
require . NoError ( t , err )
require . Equal ( t , ta . txh , h )
require . Equal ( t , ta . vub , vub )
} )
}
}
func TestTxMakers ( t * testing . T ) {
ta := new ( testAct )
ntr := New ( ta )
for name , fun := range map [ string ] func ( ) ( * transaction . Transaction , error ) {
"LockDepositUntilTransaction" : func ( ) ( * transaction . Transaction , error ) {
return ntr . LockDepositUntilTransaction ( util . Uint160 { 1 , 2 , 3 } , 100500 )
} ,
"LockDepositUntilUnsigned" : func ( ) ( * transaction . Transaction , error ) {
return ntr . LockDepositUntilUnsigned ( util . Uint160 { 1 , 2 , 3 } , 100500 )
} ,
"SetMaxNotValidBeforeDeltaTransaction" : func ( ) ( * transaction . Transaction , error ) {
return ntr . SetMaxNotValidBeforeDeltaTransaction ( 42 )
} ,
"SetMaxNotValidBeforeDeltaUnsigned" : func ( ) ( * transaction . Transaction , error ) {
return ntr . SetMaxNotValidBeforeDeltaUnsigned ( 42 )
} ,
"SetNotaryServiceFeePerKeyTransaction" : func ( ) ( * transaction . Transaction , error ) {
return ntr . SetNotaryServiceFeePerKeyTransaction ( 100500 )
} ,
"SetNotaryServiceFeePerKeyUnsigned" : func ( ) ( * transaction . Transaction , error ) {
return ntr . SetNotaryServiceFeePerKeyUnsigned ( 100500 )
} ,
"WithdrawTransaction" : func ( ) ( * transaction . Transaction , error ) {
return ntr . WithdrawTransaction ( util . Uint160 { 1 , 2 , 3 } , util . Uint160 { 3 , 2 , 1 } )
} ,
"WithdrawUnsigned" : func ( ) ( * transaction . Transaction , error ) {
return ntr . WithdrawUnsigned ( util . Uint160 { 1 , 2 , 3 } , util . Uint160 { 3 , 2 , 1 } )
} ,
} {
t . Run ( name , func ( t * testing . T ) {
ta . err = errors . New ( "" )
_ , err := fun ( )
require . Error ( t , err )
ta . err = nil
ta . tx = & transaction . Transaction { Nonce : 100500 , ValidUntilBlock : 42 }
tx , err := fun ( )
require . NoError ( t , err )
require . Equal ( t , ta . tx , tx )
} )
}
}
2023-05-15 15:04:32 +00:00
func TestOnNEP17PaymentData_Convertible ( t * testing . T ) {
t . Run ( "non-empty owner" , func ( t * testing . T ) {
d := & OnNEP17PaymentData {
Account : & util . Uint160 { 1 , 2 , 3 } ,
Till : 123 ,
}
testserdes . ToFromStackItem ( t , d , new ( OnNEP17PaymentData ) )
} )
t . Run ( "empty owner" , func ( t * testing . T ) {
d := & OnNEP17PaymentData {
Account : nil ,
Till : 123 ,
}
testserdes . ToFromStackItem ( t , d , new ( OnNEP17PaymentData ) )
} )
}
func TestOnNEP17PaymentDataToStackItem ( t * testing . T ) {
testCases := map [ string ] struct {
data * OnNEP17PaymentData
expected stackitem . Item
} {
"non-empty owner" : {
data : & OnNEP17PaymentData {
Account : & util . Uint160 { 1 , 2 , 3 } ,
Till : 123 ,
} ,
expected : stackitem . NewArray ( [ ] stackitem . Item {
stackitem . Make ( util . Uint160 { 1 , 2 , 3 } ) ,
stackitem . Make ( 123 ) ,
} ) ,
} ,
"empty owner" : {
data : & OnNEP17PaymentData {
Account : nil ,
Till : 123 ,
} ,
expected : stackitem . NewArray ( [ ] stackitem . Item {
stackitem . Null { } ,
stackitem . Make ( 123 ) ,
} ) ,
} ,
}
for name , tc := range testCases {
t . Run ( name , func ( t * testing . T ) {
actual , err := tc . data . ToStackItem ( )
require . NoError ( t , err )
require . Equal ( t , tc . expected , actual )
} )
}
}
func TestOnNEP17PaymentData_FromStackItem ( t * testing . T ) {
errCases := map [ string ] stackitem . Item {
"unexpected stackitem type" : stackitem . NewBool ( true ) ,
"unexpected number of fields" : stackitem . NewArray ( [ ] stackitem . Item { stackitem . NewBool ( true ) } ) ,
"failed to retrieve account bytes" : stackitem . NewArray ( [ ] stackitem . Item { stackitem . NewInterop ( nil ) , stackitem . Make ( 1 ) } ) ,
"failed to decode account bytes" : stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( [ ] byte { 1 } ) , stackitem . Make ( 1 ) } ) ,
"failed to retrieve till" : stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( util . Uint160 { 1 } ) , stackitem . NewInterop ( nil ) } ) ,
"till is not an int64" : stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( util . Uint160 { 1 } ) , stackitem . NewBigInteger ( new ( big . Int ) . Add ( big . NewInt ( math . MaxInt64 ) , big . NewInt ( 1 ) ) ) } ) ,
"till is larger than max uint32 value" : stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( util . Uint160 { 1 } ) , stackitem . Make ( math . MaxUint32 + 1 ) } ) ,
}
for name , errCase := range errCases {
t . Run ( name , func ( t * testing . T ) {
d := new ( OnNEP17PaymentData )
err := d . FromStackItem ( errCase )
require . Error ( t , err )
require . True ( t , strings . Contains ( err . Error ( ) , name ) , name )
} )
}
}