mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
testing and fixes for snative CALL and CallTx
This commit is contained in:
parent
b233f89dbf
commit
32e02acb0c
@ -434,30 +434,29 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
|||||||
|
|
||||||
// get or create callee
|
// get or create callee
|
||||||
if !createAccount {
|
if !createAccount {
|
||||||
if outAcc == nil {
|
|
||||||
|
if outAcc == nil || len(outAcc.Code) == 0 {
|
||||||
// check if its an snative
|
// check if its an snative
|
||||||
if _, ok := vm.RegisteredSNativeContracts[LeftPadWord256(tx.Address)]; ok {
|
if _, ok := vm.RegisteredSNativeContracts[LeftPadWord256(tx.Address)]; ok {
|
||||||
// set the outAcc (simply a placeholder until we reach the call)
|
// set the outAcc (simply a placeholder until we reach the call)
|
||||||
outAcc = &account.Account{Address: tx.Address}
|
outAcc = &account.Account{Address: tx.Address}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if outAcc == nil || len(outAcc.Code) == 0 {
|
|
||||||
// if you call an account that doesn't exist
|
|
||||||
// or an account with no code then we take fees (sorry pal)
|
|
||||||
// NOTE: it's fine to create a contract and call it within one
|
|
||||||
// block (nonce will prevent re-ordering of those txs)
|
|
||||||
// but to create with one account and call with another
|
|
||||||
// you have to wait a block to avoid a re-ordering attack
|
|
||||||
// that will take your fees
|
|
||||||
inAcc.Balance -= tx.Fee
|
|
||||||
blockCache.UpdateAccount(inAcc)
|
|
||||||
if outAcc == nil {
|
|
||||||
log.Debug(Fmt("Cannot find destination address %X. Deducting fee from caller", tx.Address))
|
|
||||||
} else {
|
} else {
|
||||||
log.Debug(Fmt("Attempting to call an account (%X) with no code. Deducting fee from caller", tx.Address))
|
// if you call an account that doesn't exist
|
||||||
|
// or an account with no code then we take fees (sorry pal)
|
||||||
|
// NOTE: it's fine to create a contract and call it within one
|
||||||
|
// block (nonce will prevent re-ordering of those txs)
|
||||||
|
// but to create with one account and call with another
|
||||||
|
// you have to wait a block to avoid a re-ordering attack
|
||||||
|
// that will take your fees
|
||||||
|
inAcc.Balance -= tx.Fee
|
||||||
|
blockCache.UpdateAccount(inAcc)
|
||||||
|
if outAcc == nil {
|
||||||
|
log.Debug(Fmt("Cannot find destination address %X. Deducting fee from caller", tx.Address))
|
||||||
|
} else {
|
||||||
|
log.Debug(Fmt("Attempting to call an account (%X) with no code. Deducting fee from caller", tx.Address))
|
||||||
|
}
|
||||||
|
return types.ErrTxInvalidAddress
|
||||||
}
|
}
|
||||||
return types.ErrTxInvalidAddress
|
|
||||||
}
|
}
|
||||||
callee = toVMAccount(outAcc)
|
callee = toVMAccount(outAcc)
|
||||||
code = callee.Code
|
code = callee.Code
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/tendermint/tendermint/events"
|
"github.com/tendermint/tendermint/events"
|
||||||
ptypes "github.com/tendermint/tendermint/permission/types"
|
ptypes "github.com/tendermint/tendermint/permission/types"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
|
"github.com/tendermint/tendermint/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -60,10 +61,6 @@ x - unknown output, without create (fail)
|
|||||||
x - unknown output, with create (pass)
|
x - unknown output, with create (pass)
|
||||||
|
|
||||||
|
|
||||||
- Gendoug:
|
|
||||||
- base: has,set,unset
|
|
||||||
- roles: has, add, r
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// keys
|
// keys
|
||||||
@ -789,6 +786,278 @@ func TestCreateAccountPermission(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- SNative (CallTx, CALL):
|
||||||
|
- for each of CallTx, Call
|
||||||
|
- call each snative without permission, fails
|
||||||
|
- call each snative with permission, pass
|
||||||
|
- list:
|
||||||
|
- base: has,set,unset
|
||||||
|
- globals: set
|
||||||
|
- roles: has, add, r
|
||||||
|
*/
|
||||||
|
|
||||||
|
func TestSNativeCALL(t *testing.T) {
|
||||||
|
stateDB := dbm.GetDB("state")
|
||||||
|
genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
|
||||||
|
genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
|
||||||
|
genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with
|
||||||
|
genDoc.Accounts[3].Permissions.AddRole("bumble")
|
||||||
|
genDoc.Accounts[3].Permissions.AddRole("bee")
|
||||||
|
st := MakeGenesisState(stateDB, &genDoc)
|
||||||
|
blockCache := NewBlockCache(st)
|
||||||
|
|
||||||
|
//----------------------------------------------------------
|
||||||
|
// Test CALL to SNative contracts
|
||||||
|
|
||||||
|
// make the main contract once
|
||||||
|
doug := &account.Account{
|
||||||
|
Address: ptypes.DougAddress,
|
||||||
|
Balance: 0,
|
||||||
|
Code: nil,
|
||||||
|
Sequence: 0,
|
||||||
|
StorageRoot: Zero256.Bytes(),
|
||||||
|
Permissions: ptypes.NewAccountPermissions(),
|
||||||
|
}
|
||||||
|
doug.Permissions.Base.Set(ptypes.Call, true)
|
||||||
|
blockCache.UpdateAccount(doug)
|
||||||
|
|
||||||
|
fmt.Println("#### hasBasePerm")
|
||||||
|
// hasBasePerm
|
||||||
|
snativeAddress, data := snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### setBasePerm")
|
||||||
|
// setBasePerm
|
||||||
|
snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.Bond, false)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.CreateContract, true)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### unsetBasePerm")
|
||||||
|
// unsetBasePerm
|
||||||
|
snativeAddress, data = snativePermTestInput("unsetBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### setGlobalPerm")
|
||||||
|
// setGlobalPerm
|
||||||
|
snativeAddress, data = snativePermTestInput("setGlobalPerm", user[3], ptypes.CreateContract, true)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// clearBasePerm
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
fmt.Println("#### hasRole")
|
||||||
|
// hasRole
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "bumble")
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### addRole")
|
||||||
|
// addRole
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
snativeAddress, data = snativeRoleTestInput("addRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### rmRole")
|
||||||
|
// rmRole
|
||||||
|
snativeAddress, data = snativeRoleTestInput("rmRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNativeCallTx(t *testing.T) {
|
||||||
|
stateDB := dbm.GetDB("state")
|
||||||
|
genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
|
||||||
|
genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
|
||||||
|
genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with
|
||||||
|
genDoc.Accounts[3].Permissions.AddRole("bumble")
|
||||||
|
genDoc.Accounts[3].Permissions.AddRole("bee")
|
||||||
|
st := MakeGenesisState(stateDB, &genDoc)
|
||||||
|
blockCache := NewBlockCache(st)
|
||||||
|
|
||||||
|
//----------------------------------------------------------
|
||||||
|
// Test CallTx to SNative contracts
|
||||||
|
var doug *account.Account = nil
|
||||||
|
|
||||||
|
fmt.Println("#### hasBasePerm")
|
||||||
|
// hasBasePerm
|
||||||
|
snativeAddress, data := snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### setBasePerm")
|
||||||
|
// setBasePerm
|
||||||
|
snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.Bond, false)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.CreateContract, true)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### unsetBasePerm")
|
||||||
|
// unsetBasePerm
|
||||||
|
snativeAddress, data = snativePermTestInput("unsetBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### setGlobalPerm")
|
||||||
|
// setGlobalPerm
|
||||||
|
snativeAddress, data = snativePermTestInput("setGlobalPerm", user[3], ptypes.CreateContract, true)
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
// return value should be true or false as a 32 byte array...
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// clearBasePerm
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
fmt.Println("#### hasRole")
|
||||||
|
// hasRole
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "bumble")
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### addRole")
|
||||||
|
// addRole
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
snativeAddress, data = snativeRoleTestInput("addRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret[:31]) || ret[31] != byte(1) {
|
||||||
|
return fmt.Errorf("Expected 1. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println("#### rmRole")
|
||||||
|
// rmRole
|
||||||
|
snativeAddress, data = snativeRoleTestInput("rmRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
|
||||||
|
snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
|
||||||
|
testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
|
||||||
|
if !IsZeros(ret) {
|
||||||
|
return fmt.Errorf("Expected 0. Got %X", ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// helpers
|
// helpers
|
||||||
|
|
||||||
@ -821,11 +1090,95 @@ func execTxWaitEvent(t *testing.T, blockCache *BlockCache, tx types.Tx, eventid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds
|
||||||
|
func testSNativeCALLExpectPass(t *testing.T, blockCache *BlockCache, doug *account.Account, snativeAddress, data []byte, f func([]byte) error) {
|
||||||
|
perm := vm.RegisteredSNativeContracts[LeftPadWord256(snativeAddress)]
|
||||||
|
var addr []byte
|
||||||
|
if doug != nil {
|
||||||
|
contractCode := callContractCode(snativeAddress)
|
||||||
|
doug.Code = contractCode
|
||||||
|
doug.Permissions.Base.Set(perm, true)
|
||||||
|
blockCache.UpdateAccount(doug)
|
||||||
|
addr = doug.Address
|
||||||
|
} else {
|
||||||
|
acc := blockCache.GetAccount(user[0].Address)
|
||||||
|
acc.Permissions.Base.Set(perm, true)
|
||||||
|
blockCache.UpdateAccount(acc)
|
||||||
|
addr = snativeAddress
|
||||||
|
}
|
||||||
|
tx, _ := types.NewCallTx(blockCache, user[0].PubKey, addr, data, 100, 10000, 100)
|
||||||
|
tx.Sign(user[0])
|
||||||
|
ev, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(snativeAddress)) //
|
||||||
|
if exception != "" {
|
||||||
|
t.Fatal("Unexpected exception", exception)
|
||||||
|
}
|
||||||
|
evv := ev.(types.EventMsgCall)
|
||||||
|
ret := evv.Return
|
||||||
|
if err := f(ret); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assumes the contract has not been given the permission. calls the it, it calls the snative, expects to fail
|
||||||
|
func testSNativeCALLExpectFail(t *testing.T, blockCache *BlockCache, doug *account.Account, snativeAddress, data []byte) {
|
||||||
|
var addr []byte
|
||||||
|
if doug != nil {
|
||||||
|
contractCode := callContractCode(snativeAddress)
|
||||||
|
doug.Code = contractCode
|
||||||
|
blockCache.UpdateAccount(doug)
|
||||||
|
addr = doug.Address
|
||||||
|
} else {
|
||||||
|
addr = snativeAddress
|
||||||
|
}
|
||||||
|
tx, _ := types.NewCallTx(blockCache, user[0].PubKey, addr, data, 100, 10000, 100)
|
||||||
|
tx.Sign(user[0])
|
||||||
|
fmt.Println("subscribing to", types.EventStringAccReceive(snativeAddress))
|
||||||
|
_, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(snativeAddress))
|
||||||
|
if exception == "" {
|
||||||
|
t.Fatal("Expected exception")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolToWord256(v bool) Word256 {
|
||||||
|
var vint byte
|
||||||
|
if v {
|
||||||
|
vint = 0x1
|
||||||
|
} else {
|
||||||
|
vint = 0x0
|
||||||
|
}
|
||||||
|
return LeftPadWord256([]byte{vint})
|
||||||
|
}
|
||||||
|
|
||||||
|
func snativePermTestInput(name string, user *account.PrivAccount, perm ptypes.PermFlag, val bool) (addr []byte, data []byte) {
|
||||||
|
addr = LeftPadWord256([]byte(name)).Postfix(20)
|
||||||
|
switch name {
|
||||||
|
case "hasBasePerm", "unsetBasePerm":
|
||||||
|
data = LeftPadBytes(user.Address, 32)
|
||||||
|
data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...)
|
||||||
|
case "setBasePerm":
|
||||||
|
data = LeftPadBytes(user.Address, 32)
|
||||||
|
data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...)
|
||||||
|
data = append(data, boolToWord256(val).Bytes()...)
|
||||||
|
case "setGlobalPerm":
|
||||||
|
data = Uint64ToWord256(uint64(perm)).Bytes()
|
||||||
|
data = append(data, boolToWord256(val).Bytes()...)
|
||||||
|
case "clearBasePerm":
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func snativeRoleTestInput(name string, user *account.PrivAccount, role string) (addr []byte, data []byte) {
|
||||||
|
addr = LeftPadWord256([]byte(name)).Postfix(20)
|
||||||
|
data = LeftPadBytes(user.Address, 32)
|
||||||
|
data = append(data, LeftPadBytes([]byte(role), 32)...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// convenience function for contract that calls a given address
|
// convenience function for contract that calls a given address
|
||||||
func callContractCode(contractAddr []byte) []byte {
|
func callContractCode(contractAddr []byte) []byte {
|
||||||
// calldatacopy into mem and use as input to call
|
// calldatacopy into mem and use as input to call
|
||||||
memOff, inputOff := byte(0x0), byte(0x0)
|
memOff, inputOff := byte(0x0), byte(0x0)
|
||||||
contractCode := []byte{0x60, memOff, 0x60, inputOff, 0x36, 0x37}
|
contractCode := []byte{0x36, 0x60, inputOff, 0x60, memOff, 0x37}
|
||||||
|
|
||||||
gas1, gas2 := byte(0x1), byte(0x1)
|
gas1, gas2 := byte(0x1), byte(0x1)
|
||||||
value := byte(0x1)
|
value := byte(0x1)
|
||||||
|
@ -111,6 +111,7 @@ func (vm *VM) hasBasePerm(acc *Account, args []byte) (output []byte, err error)
|
|||||||
} else {
|
} else {
|
||||||
permInt = 0x0
|
permInt = 0x0
|
||||||
}
|
}
|
||||||
|
dbg.Printf("snative.hasBasePerm(0x%X, %b) = %v\n", addr.Postfix(20), permN, permInt)
|
||||||
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +139,7 @@ func (vm *VM) setBasePerm(acc *Account, args []byte) (output []byte, err error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
vm.appState.UpdateAccount(vmAcc)
|
||||||
|
dbg.Printf("snative.setBasePerm(0x%X, %b, %v)\n", addr.Postfix(20), permN, permV)
|
||||||
return perm.Bytes(), nil
|
return perm.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +165,7 @@ func (vm *VM) unsetBasePerm(acc *Account, args []byte) (output []byte, err error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
vm.appState.UpdateAccount(vmAcc)
|
||||||
|
dbg.Printf("snative.unsetBasePerm(0x%X, %b)\n", addr.Postfix(20), permN)
|
||||||
return permNum.Bytes(), nil
|
return permNum.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,11 +174,11 @@ func (vm *VM) setGlobalPerm(acc *Account, args []byte) (output []byte, err error
|
|||||||
return nil, ErrInvalidPermission{acc.Address, "SetGlobalPerm"}
|
return nil, ErrInvalidPermission{acc.Address, "SetGlobalPerm"}
|
||||||
}
|
}
|
||||||
if len(args) != 2*32 {
|
if len(args) != 2*32 {
|
||||||
return nil, fmt.Errorf("setGlobalPerm() takes three arguments (permission number, permission value)")
|
return nil, fmt.Errorf("setGlobalPerm() takes two arguments (permission number, permission value)")
|
||||||
}
|
}
|
||||||
var permNum, perm Word256
|
var permNum, perm Word256
|
||||||
copy(permNum[:], args[32:64])
|
copy(permNum[:], args[:32])
|
||||||
copy(perm[:], args[64:96])
|
copy(perm[:], args[32:64])
|
||||||
vmAcc := vm.appState.GetAccount(ptypes.GlobalPermissionsAddress256)
|
vmAcc := vm.appState.GetAccount(ptypes.GlobalPermissionsAddress256)
|
||||||
if vmAcc == nil {
|
if vmAcc == nil {
|
||||||
panic("cant find the global permissions account")
|
panic("cant find the global permissions account")
|
||||||
@ -189,6 +192,7 @@ func (vm *VM) setGlobalPerm(acc *Account, args []byte) (output []byte, err error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
vm.appState.UpdateAccount(vmAcc)
|
||||||
|
dbg.Printf("snative.setGlobalPerm(%b, %v)\n", permN, permV)
|
||||||
return perm.Bytes(), nil
|
return perm.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,8 +212,8 @@ func (vm *VM) hasRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
return nil, fmt.Errorf("hasRole() takes two arguments (address, role)")
|
return nil, fmt.Errorf("hasRole() takes two arguments (address, role)")
|
||||||
}
|
}
|
||||||
var addr, role Word256
|
var addr, role Word256
|
||||||
copy(addr[:], args[32:64])
|
copy(addr[:], args[:32])
|
||||||
copy(role[:], args[64:96])
|
copy(role[:], args[32:64])
|
||||||
vmAcc := vm.appState.GetAccount(addr)
|
vmAcc := vm.appState.GetAccount(addr)
|
||||||
if vmAcc == nil {
|
if vmAcc == nil {
|
||||||
return nil, fmt.Errorf("Unknown account %X", addr)
|
return nil, fmt.Errorf("Unknown account %X", addr)
|
||||||
@ -221,6 +225,7 @@ func (vm *VM) hasRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
} else {
|
} else {
|
||||||
permInt = 0x0
|
permInt = 0x0
|
||||||
}
|
}
|
||||||
|
dbg.Printf("snative.hasRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0)
|
||||||
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,8 +237,8 @@ func (vm *VM) addRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
return nil, fmt.Errorf("addRole() takes two arguments (address, role)")
|
return nil, fmt.Errorf("addRole() takes two arguments (address, role)")
|
||||||
}
|
}
|
||||||
var addr, role Word256
|
var addr, role Word256
|
||||||
copy(addr[:], args[32:64])
|
copy(addr[:], args[:32])
|
||||||
copy(role[:], args[64:96])
|
copy(role[:], args[32:64])
|
||||||
vmAcc := vm.appState.GetAccount(addr)
|
vmAcc := vm.appState.GetAccount(addr)
|
||||||
if vmAcc == nil {
|
if vmAcc == nil {
|
||||||
return nil, fmt.Errorf("Unknown account %X", addr)
|
return nil, fmt.Errorf("Unknown account %X", addr)
|
||||||
@ -245,6 +250,8 @@ func (vm *VM) addRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
} else {
|
} else {
|
||||||
permInt = 0x0
|
permInt = 0x0
|
||||||
}
|
}
|
||||||
|
vm.appState.UpdateAccount(vmAcc)
|
||||||
|
dbg.Printf("snative.addRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0)
|
||||||
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,8 +263,8 @@ func (vm *VM) rmRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
return nil, fmt.Errorf("rmRole() takes two arguments (address, role)")
|
return nil, fmt.Errorf("rmRole() takes two arguments (address, role)")
|
||||||
}
|
}
|
||||||
var addr, role Word256
|
var addr, role Word256
|
||||||
copy(addr[:], args[32:64])
|
copy(addr[:], args[:32])
|
||||||
copy(role[:], args[64:96])
|
copy(role[:], args[32:64])
|
||||||
vmAcc := vm.appState.GetAccount(addr)
|
vmAcc := vm.appState.GetAccount(addr)
|
||||||
if vmAcc == nil {
|
if vmAcc == nil {
|
||||||
return nil, fmt.Errorf("Unknown account %X", addr)
|
return nil, fmt.Errorf("Unknown account %X", addr)
|
||||||
@ -269,5 +276,7 @@ func (vm *VM) rmRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
} else {
|
} else {
|
||||||
permInt = 0x0
|
permInt = 0x0
|
||||||
}
|
}
|
||||||
|
vm.appState.UpdateAccount(vmAcc)
|
||||||
|
dbg.Printf("snative.rmRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0)
|
||||||
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user