mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-29 14:11:21 +00:00
snatives take appState as arg (rather than vm receiver)
This commit is contained in:
parent
26d64412b3
commit
883dbcc027
@ -1091,7 +1091,7 @@ 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
|
// 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) {
|
func testSNativeCALLExpectPass(t *testing.T, blockCache *BlockCache, doug *account.Account, snativeAddress, data []byte, f func([]byte) error) {
|
||||||
perm := vm.RegisteredSNativeContracts[LeftPadWord256(snativeAddress)]
|
perm := vm.RegisteredSNativePermissions[LeftPadWord256(snativeAddress)]
|
||||||
var addr []byte
|
var addr []byte
|
||||||
if doug != nil {
|
if doug != nil {
|
||||||
contractCode := callContractCode(snativeAddress)
|
contractCode := callContractCode(snativeAddress)
|
||||||
|
200
vm/snative.go
200
vm/snative.go
@ -7,24 +7,8 @@ import (
|
|||||||
ptypes "github.com/tendermint/tendermint/permission/types"
|
ptypes "github.com/tendermint/tendermint/permission/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ErrInvalidPermission struct {
|
//------------------------------------------------------------------------------------------------
|
||||||
Address Word256
|
// Registered SNative contracts
|
||||||
SNative string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ErrInvalidPermission) Error() string {
|
|
||||||
return fmt.Sprintf("Account %X does not have permission snative.%s", e.Address.Postfix(20), e.SNative)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if a permission flag is valid (a known base chain or snative permission)
|
|
||||||
func ValidPermN(n ptypes.PermFlag) bool {
|
|
||||||
if n > ptypes.TopBasePermission && n < FirstSNativePerm {
|
|
||||||
return false
|
|
||||||
} else if n > TopSNativePermission {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// first 32 bits of BasePermission are for chain, second 32 are for snative
|
// first 32 bits of BasePermission are for chain, second 32 are for snative
|
||||||
@ -45,41 +29,20 @@ const (
|
|||||||
TopSNativePermission ptypes.PermFlag = FirstSNativePerm << (NumSNativePermissions - 1)
|
TopSNativePermission ptypes.PermFlag = FirstSNativePerm << (NumSNativePermissions - 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
var RegisteredSNativeContracts = map[Word256]ptypes.PermFlag{
|
var RegisteredSNativeContracts = map[Word256]SNativeContract{
|
||||||
LeftPadWord256([]byte("hasBasePerm")): HasBasePerm,
|
LeftPadWord256([]byte("hasBasePerm")): hasBasePerm,
|
||||||
LeftPadWord256([]byte("setBasePerm")): SetBasePerm,
|
LeftPadWord256([]byte("setBasePerm")): setBasePerm,
|
||||||
LeftPadWord256([]byte("unsetBasePerm")): UnsetBasePerm,
|
LeftPadWord256([]byte("unsetBasePerm")): unsetBasePerm,
|
||||||
LeftPadWord256([]byte("setGlobalPerm")): SetGlobalPerm,
|
LeftPadWord256([]byte("setGlobalPerm")): setGlobalPerm,
|
||||||
LeftPadWord256([]byte("hasRole")): HasRole,
|
LeftPadWord256([]byte("hasRole")): hasRole,
|
||||||
LeftPadWord256([]byte("addRole")): AddRole,
|
LeftPadWord256([]byte("addRole")): addRole,
|
||||||
LeftPadWord256([]byte("rmRole")): RmRole,
|
LeftPadWord256([]byte("rmRole")): rmRole,
|
||||||
}
|
}
|
||||||
|
|
||||||
// takes an account so it can check for permission to access the contract
|
// Takes an appState so it can lookup/update accounts,
|
||||||
// NOTE: the account is the currently executing account (the callee), not say an origin caller
|
// an account to check for permission to access the snative contract
|
||||||
type SNativeContract func(acc *Account, input []byte) (output []byte, err error)
|
// and some input bytes (presumably 32byte words)
|
||||||
|
type SNativeContract func(appState AppState, acc *Account, input []byte) (output []byte, err error)
|
||||||
func (vm *VM) SNativeContract(name Word256) SNativeContract {
|
|
||||||
flag := RegisteredSNativeContracts[name]
|
|
||||||
switch flag {
|
|
||||||
case HasBasePerm:
|
|
||||||
return vm.hasBasePerm
|
|
||||||
case SetBasePerm:
|
|
||||||
return vm.setBasePerm
|
|
||||||
case UnsetBasePerm:
|
|
||||||
return vm.unsetBasePerm
|
|
||||||
case SetGlobalPerm:
|
|
||||||
return vm.setGlobalPerm
|
|
||||||
case HasRole:
|
|
||||||
return vm.hasRole
|
|
||||||
case AddRole:
|
|
||||||
return vm.addRole
|
|
||||||
case RmRole:
|
|
||||||
return vm.rmRole
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// snative are native contracts that can access and manipulate the chain state
|
// snative are native contracts that can access and manipulate the chain state
|
||||||
@ -87,17 +50,15 @@ func (vm *VM) SNativeContract(name Word256) SNativeContract {
|
|||||||
|
|
||||||
// TODO: catch errors, log em, return 0s to the vm (should some errors cause exceptions though?)
|
// TODO: catch errors, log em, return 0s to the vm (should some errors cause exceptions though?)
|
||||||
|
|
||||||
func (vm *VM) hasBasePerm(acc *Account, args []byte) (output []byte, err error) {
|
func hasBasePerm(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, HasBasePerm) {
|
if !HasPermission(appState, acc, HasBasePerm) {
|
||||||
return nil, ErrInvalidPermission{acc.Address, "HasBasePerm"}
|
return nil, ErrInvalidPermission{acc.Address, "HasBasePerm"}
|
||||||
}
|
}
|
||||||
if len(args) != 2*32 {
|
if len(args) != 2*32 {
|
||||||
return nil, fmt.Errorf("hasBasePerm() takes two arguments (address, permission number)")
|
return nil, fmt.Errorf("hasBasePerm() takes two arguments (address, permission number)")
|
||||||
}
|
}
|
||||||
var addr, permNum Word256
|
addr, permNum := returnTwoArgs(args)
|
||||||
copy(addr[:], args[:32])
|
vmAcc := appState.GetAccount(addr)
|
||||||
copy(permNum[:], args[32:64])
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -106,7 +67,7 @@ func (vm *VM) hasBasePerm(acc *Account, args []byte) (output []byte, err error)
|
|||||||
return nil, ptypes.ErrInvalidPermission(permN)
|
return nil, ptypes.ErrInvalidPermission(permN)
|
||||||
}
|
}
|
||||||
var permInt byte
|
var permInt byte
|
||||||
if vm.HasPermission(vmAcc, permN) {
|
if HasPermission(appState, vmAcc, permN) {
|
||||||
permInt = 0x1
|
permInt = 0x1
|
||||||
} else {
|
} else {
|
||||||
permInt = 0x0
|
permInt = 0x0
|
||||||
@ -115,18 +76,15 @@ func (vm *VM) hasBasePerm(acc *Account, args []byte) (output []byte, err error)
|
|||||||
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) setBasePerm(acc *Account, args []byte) (output []byte, err error) {
|
func setBasePerm(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, SetBasePerm) {
|
if !HasPermission(appState, acc, SetBasePerm) {
|
||||||
return nil, ErrInvalidPermission{acc.Address, "SetBasePerm"}
|
return nil, ErrInvalidPermission{acc.Address, "SetBasePerm"}
|
||||||
}
|
}
|
||||||
if len(args) != 3*32 {
|
if len(args) != 3*32 {
|
||||||
return nil, fmt.Errorf("setBasePerm() takes three arguments (address, permission number, permission value)")
|
return nil, fmt.Errorf("setBasePerm() takes three arguments (address, permission number, permission value)")
|
||||||
}
|
}
|
||||||
var addr, permNum, perm Word256
|
addr, permNum, perm := returnThreeArgs(args)
|
||||||
copy(addr[:], args[:32])
|
vmAcc := appState.GetAccount(addr)
|
||||||
copy(permNum[:], args[32:64])
|
|
||||||
copy(perm[:], args[64:96])
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -138,22 +96,20 @@ func (vm *VM) setBasePerm(acc *Account, args []byte) (output []byte, err error)
|
|||||||
if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil {
|
if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
appState.UpdateAccount(vmAcc)
|
||||||
dbg.Printf("snative.setBasePerm(0x%X, %b, %v)\n", addr.Postfix(20), permN, permV)
|
dbg.Printf("snative.setBasePerm(0x%X, %b, %v)\n", addr.Postfix(20), permN, permV)
|
||||||
return perm.Bytes(), nil
|
return perm.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) unsetBasePerm(acc *Account, args []byte) (output []byte, err error) {
|
func unsetBasePerm(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, UnsetBasePerm) {
|
if !HasPermission(appState, acc, UnsetBasePerm) {
|
||||||
return nil, ErrInvalidPermission{acc.Address, "UnsetBasePerm"}
|
return nil, ErrInvalidPermission{acc.Address, "UnsetBasePerm"}
|
||||||
}
|
}
|
||||||
if len(args) != 2*32 {
|
if len(args) != 2*32 {
|
||||||
return nil, fmt.Errorf("unsetBasePerm() takes two arguments (address, permission number)")
|
return nil, fmt.Errorf("unsetBasePerm() takes two arguments (address, permission number)")
|
||||||
}
|
}
|
||||||
var addr, permNum Word256
|
addr, permNum := returnTwoArgs(args)
|
||||||
copy(addr[:], args[:32])
|
vmAcc := appState.GetAccount(addr)
|
||||||
copy(permNum[:], args[32:64])
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -164,22 +120,20 @@ func (vm *VM) unsetBasePerm(acc *Account, args []byte) (output []byte, err error
|
|||||||
if err = vmAcc.Permissions.Base.Unset(permN); err != nil {
|
if err = vmAcc.Permissions.Base.Unset(permN); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
appState.UpdateAccount(vmAcc)
|
||||||
dbg.Printf("snative.unsetBasePerm(0x%X, %b)\n", addr.Postfix(20), permN)
|
dbg.Printf("snative.unsetBasePerm(0x%X, %b)\n", addr.Postfix(20), permN)
|
||||||
return permNum.Bytes(), nil
|
return permNum.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) setGlobalPerm(acc *Account, args []byte) (output []byte, err error) {
|
func setGlobalPerm(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, SetGlobalPerm) {
|
if !HasPermission(appState, acc, SetGlobalPerm) {
|
||||||
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 two arguments (permission number, permission value)")
|
return nil, fmt.Errorf("setGlobalPerm() takes two arguments (permission number, permission value)")
|
||||||
}
|
}
|
||||||
var permNum, perm Word256
|
permNum, perm := returnTwoArgs(args)
|
||||||
copy(permNum[:], args[:32])
|
vmAcc := appState.GetAccount(ptypes.GlobalPermissionsAddress256)
|
||||||
copy(perm[:], args[32:64])
|
|
||||||
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")
|
||||||
}
|
}
|
||||||
@ -191,30 +145,28 @@ func (vm *VM) setGlobalPerm(acc *Account, args []byte) (output []byte, err error
|
|||||||
if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil {
|
if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
appState.UpdateAccount(vmAcc)
|
||||||
dbg.Printf("snative.setGlobalPerm(%b, %v)\n", permN, permV)
|
dbg.Printf("snative.setGlobalPerm(%b, %v)\n", permN, permV)
|
||||||
return perm.Bytes(), nil
|
return perm.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: needs access to an iterator ...
|
// TODO: needs access to an iterator ...
|
||||||
func (vm *VM) clearPerm(acc *Account, args []byte) (output []byte, err error) {
|
func clearPerm(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, ClearBasePerm) {
|
if !HasPermission(appState, acc, ClearBasePerm) {
|
||||||
return nil, ErrInvalidPermission{acc.Address, "ClearPerm"}
|
return nil, ErrInvalidPermission{acc.Address, "ClearPerm"}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) hasRole(acc *Account, args []byte) (output []byte, err error) {
|
func hasRole(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, HasRole) {
|
if !HasPermission(appState, acc, HasRole) {
|
||||||
return nil, ErrInvalidPermission{acc.Address, "HasRole"}
|
return nil, ErrInvalidPermission{acc.Address, "HasRole"}
|
||||||
}
|
}
|
||||||
if len(args) != 2*32 {
|
if len(args) != 2*32 {
|
||||||
return nil, fmt.Errorf("hasRole() takes two arguments (address, role)")
|
return nil, fmt.Errorf("hasRole() takes two arguments (address, role)")
|
||||||
}
|
}
|
||||||
var addr, role Word256
|
addr, role := returnTwoArgs(args)
|
||||||
copy(addr[:], args[:32])
|
vmAcc := appState.GetAccount(addr)
|
||||||
copy(role[:], args[32:64])
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -229,17 +181,15 @@ func (vm *VM) hasRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
return LeftPadWord256([]byte{permInt}).Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) addRole(acc *Account, args []byte) (output []byte, err error) {
|
func addRole(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, AddRole) {
|
if !HasPermission(appState, acc, AddRole) {
|
||||||
return nil, ErrInvalidPermission{acc.Address, "AddRole"}
|
return nil, ErrInvalidPermission{acc.Address, "AddRole"}
|
||||||
}
|
}
|
||||||
if len(args) != 2*32 {
|
if len(args) != 2*32 {
|
||||||
return nil, fmt.Errorf("addRole() takes two arguments (address, role)")
|
return nil, fmt.Errorf("addRole() takes two arguments (address, role)")
|
||||||
}
|
}
|
||||||
var addr, role Word256
|
addr, role := returnTwoArgs(args)
|
||||||
copy(addr[:], args[:32])
|
vmAcc := appState.GetAccount(addr)
|
||||||
copy(role[:], args[32:64])
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -250,22 +200,20 @@ func (vm *VM) addRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
} else {
|
} else {
|
||||||
permInt = 0x0
|
permInt = 0x0
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
appState.UpdateAccount(vmAcc)
|
||||||
dbg.Printf("snative.addRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) rmRole(acc *Account, args []byte) (output []byte, err error) {
|
func rmRole(appState AppState, acc *Account, args []byte) (output []byte, err error) {
|
||||||
if !vm.HasPermission(acc, RmRole) {
|
if !HasPermission(appState, acc, RmRole) {
|
||||||
return nil, ErrInvalidPermission{acc.Address, "RmRole"}
|
return nil, ErrInvalidPermission{acc.Address, "RmRole"}
|
||||||
}
|
}
|
||||||
if len(args) != 2*32 {
|
if len(args) != 2*32 {
|
||||||
return nil, fmt.Errorf("rmRole() takes two arguments (address, role)")
|
return nil, fmt.Errorf("rmRole() takes two arguments (address, role)")
|
||||||
}
|
}
|
||||||
var addr, role Word256
|
addr, role := returnTwoArgs(args)
|
||||||
copy(addr[:], args[:32])
|
vmAcc := appState.GetAccount(addr)
|
||||||
copy(role[:], args[32:64])
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -276,7 +224,55 @@ func (vm *VM) rmRole(acc *Account, args []byte) (output []byte, err error) {
|
|||||||
} else {
|
} else {
|
||||||
permInt = 0x0
|
permInt = 0x0
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(vmAcc)
|
appState.UpdateAccount(vmAcc)
|
||||||
dbg.Printf("snative.rmRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
// Errors and utility funcs
|
||||||
|
|
||||||
|
type ErrInvalidPermission struct {
|
||||||
|
Address Word256
|
||||||
|
SNative string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrInvalidPermission) Error() string {
|
||||||
|
return fmt.Sprintf("Account %X does not have permission snative.%s", e.Address.Postfix(20), e.SNative)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if a permission flag is valid (a known base chain or snative permission)
|
||||||
|
func ValidPermN(n ptypes.PermFlag) bool {
|
||||||
|
if n > ptypes.TopBasePermission && n < FirstSNativePerm {
|
||||||
|
return false
|
||||||
|
} else if n > TopSNativePermission {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// assumes length has already been checked
|
||||||
|
func returnTwoArgs(args []byte) (a Word256, b Word256) {
|
||||||
|
copy(a[:], args[:32])
|
||||||
|
copy(b[:], args[32:64])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// assumes length has already been checked
|
||||||
|
func returnThreeArgs(args []byte) (a Word256, b Word256, c Word256) {
|
||||||
|
copy(a[:], args[:32])
|
||||||
|
copy(b[:], args[32:64])
|
||||||
|
copy(c[:], args[64:96])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// mostly a convenience for testing
|
||||||
|
var RegisteredSNativePermissions = map[Word256]ptypes.PermFlag{
|
||||||
|
LeftPadWord256([]byte("hasBasePerm")): HasBasePerm,
|
||||||
|
LeftPadWord256([]byte("setBasePerm")): SetBasePerm,
|
||||||
|
LeftPadWord256([]byte("unsetBasePerm")): UnsetBasePerm,
|
||||||
|
LeftPadWord256([]byte("setGlobalPerm")): SetGlobalPerm,
|
||||||
|
LeftPadWord256([]byte("hasRole")): HasRole,
|
||||||
|
LeftPadWord256([]byte("addRole")): AddRole,
|
||||||
|
LeftPadWord256([]byte("rmRole")): RmRole,
|
||||||
|
}
|
||||||
|
17
vm/vm.go
17
vm/vm.go
@ -90,10 +90,13 @@ func (vm *VM) EnablePermissions() {
|
|||||||
vm.perms = true
|
vm.perms = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) HasPermission(acc *Account, perm ptypes.PermFlag) bool {
|
func HasPermission(appState AppState, acc *Account, perm ptypes.PermFlag) bool {
|
||||||
v, err := acc.Permissions.Base.Get(perm)
|
v, err := acc.Permissions.Base.Get(perm)
|
||||||
if _, ok := err.(ptypes.ErrValueNotSet); ok {
|
if _, ok := err.(ptypes.ErrValueNotSet); ok {
|
||||||
return vm.HasPermission(vm.appState.GetAccount(ptypes.GlobalPermissionsAddress256), perm)
|
if appState == nil {
|
||||||
|
panic(fmt.Sprintf("Global permission value not set for %b", perm))
|
||||||
|
}
|
||||||
|
return HasPermission(nil, appState.GetAccount(ptypes.GlobalPermissionsAddress256), perm)
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
@ -119,8 +122,8 @@ func (vm *VM) Call(caller, callee *Account, code, input []byte, value int64, gas
|
|||||||
|
|
||||||
// if code is empty, callee may be snative contract
|
// if code is empty, callee may be snative contract
|
||||||
if vm.snative && len(code) == 0 {
|
if vm.snative && len(code) == 0 {
|
||||||
if snativeContract := vm.SNativeContract(callee.Address); snativeContract != nil {
|
if snativeContract, ok := RegisteredSNativeContracts[callee.Address]; ok {
|
||||||
output, err = snativeContract(caller, input)
|
output, err = snativeContract(vm.appState, caller, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
*exception = err.Error()
|
*exception = err.Error()
|
||||||
}
|
}
|
||||||
@ -700,7 +703,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
|
|||||||
dbg.Printf(" => %v\n", log)
|
dbg.Printf(" => %v\n", log)
|
||||||
|
|
||||||
case CREATE: // 0xF0
|
case CREATE: // 0xF0
|
||||||
if vm.perms && !vm.HasPermission(callee, ptypes.CreateContract) {
|
if vm.perms && !HasPermission(vm.appState, callee, ptypes.CreateContract) {
|
||||||
return nil, ErrPermission{"create_contract"}
|
return nil, ErrPermission{"create_contract"}
|
||||||
}
|
}
|
||||||
contractValue := stack.Pop64()
|
contractValue := stack.Pop64()
|
||||||
@ -728,7 +731,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CALL, CALLCODE: // 0xF1, 0xF2
|
case CALL, CALLCODE: // 0xF1, 0xF2
|
||||||
if vm.perms && !vm.HasPermission(callee, ptypes.Call) {
|
if vm.perms && !HasPermission(vm.appState, callee, ptypes.Call) {
|
||||||
return nil, ErrPermission{"call"}
|
return nil, ErrPermission{"call"}
|
||||||
}
|
}
|
||||||
gasLimit := stack.Pop64()
|
gasLimit := stack.Pop64()
|
||||||
@ -779,7 +782,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
|
|||||||
} else {
|
} else {
|
||||||
// if we have not seen the account before, create it
|
// if we have not seen the account before, create it
|
||||||
// so we can send funds
|
// so we can send funds
|
||||||
if vm.perms && !vm.HasPermission(caller, ptypes.CreateAccount) {
|
if vm.perms && !HasPermission(vm.appState, caller, ptypes.CreateAccount) {
|
||||||
return nil, ErrPermission{"create_account"}
|
return nil, ErrPermission{"create_account"}
|
||||||
}
|
}
|
||||||
acc = &Account{Address: addr}
|
acc = &Account{Address: addr}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user