mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-19 01:51:19 +00:00
faster binding of snatives to vm (available every call)
This commit is contained in:
parent
f75b6aff74
commit
b2282d5a39
@ -361,7 +361,6 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
|||||||
|
|
||||||
case *types.CallTx:
|
case *types.CallTx:
|
||||||
var inAcc, outAcc *account.Account
|
var inAcc, outAcc *account.Account
|
||||||
var isDoug bool // is this a call to the gendoug?
|
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
inAcc = blockCache.GetAccount(tx.Input.Address)
|
inAcc = blockCache.GetAccount(tx.Input.Address)
|
||||||
@ -466,14 +465,11 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
|||||||
txCache.UpdateAccount(callee) // because we adjusted by input above.
|
txCache.UpdateAccount(callee) // because we adjusted by input above.
|
||||||
vmach := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(_s.ChainID, tx))
|
vmach := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(_s.ChainID, tx))
|
||||||
vmach.SetFireable(evc)
|
vmach.SetFireable(evc)
|
||||||
vmach.EnablePermissions()
|
|
||||||
|
vmach.EnablePermissions() // permission checks on CALL/CREATE
|
||||||
|
vmach.EnableSNatives() // allows calls to snatives (with permission checks)
|
||||||
|
|
||||||
// NOTE: Call() transfers the value from caller to callee iff call succeeds.
|
// NOTE: Call() transfers the value from caller to callee iff call succeeds.
|
||||||
|
|
||||||
if isDoug {
|
|
||||||
// enables the snative contracts
|
|
||||||
vmach.EnableDoug() // setupDoug(vmach, txCache, _s)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret, err := vmach.Call(caller, callee, code, tx.Data, value, &gas)
|
ret, err := vmach.Call(caller, callee, code, tx.Data, value, &gas)
|
||||||
exception := ""
|
exception := ""
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,6 +21,7 @@ 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
|
||||||
FirstSNativePerm ptypes.PermFlag = 1 << 32
|
FirstSNativePerm ptypes.PermFlag = 1 << 32
|
||||||
|
|
||||||
|
// each snative has an associated permission flag
|
||||||
HasBasePerm ptypes.PermFlag = FirstSNativePerm << iota
|
HasBasePerm ptypes.PermFlag = FirstSNativePerm << iota
|
||||||
SetBasePerm
|
SetBasePerm
|
||||||
UnsetBasePerm
|
UnsetBasePerm
|
||||||
@ -35,8 +36,42 @@ const (
|
|||||||
TopSNativePermission ptypes.PermFlag = FirstSNativePerm << (NumSNativePermissions - 1)
|
TopSNativePermission ptypes.PermFlag = FirstSNativePerm << (NumSNativePermissions - 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var registeredSNativeContracts = map[Word256]ptypes.PermFlag{
|
||||||
|
RightPadWord256([]byte("hasBasePerm")): HasBasePerm,
|
||||||
|
RightPadWord256([]byte("setBasePerm")): SetBasePerm,
|
||||||
|
RightPadWord256([]byte("unsetBasePerm")): UnsetBasePerm,
|
||||||
|
RightPadWord256([]byte("setGlobalPerm")): SetGlobalPerm,
|
||||||
|
RightPadWord256([]byte("hasRole")): HasRole,
|
||||||
|
RightPadWord256([]byte("addRole")): AddRole,
|
||||||
|
RightPadWord256([]byte("rmRole")): RmRole,
|
||||||
|
}
|
||||||
|
|
||||||
|
// takes an account so it can check for permission to access the contract
|
||||||
|
// NOTE: the account is the currently executing account (the callee), not say an origin caller
|
||||||
type SNativeContract func(acc *Account, input []byte) (output []byte, err error)
|
type SNativeContract func(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
|
||||||
// (in particular the permissions values)
|
// (in particular the permissions values)
|
||||||
|
22
vm/vm.go
22
vm/vm.go
@ -61,9 +61,8 @@ type VM struct {
|
|||||||
|
|
||||||
evc events.Fireable
|
evc events.Fireable
|
||||||
|
|
||||||
doug bool // is this the gendoug contract
|
|
||||||
perms bool // permission checking can be turned off
|
perms bool // permission checking can be turned off
|
||||||
snativeContracts map[Word256]SNativeContract
|
snative bool // access to snatives
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVM(appState AppState, params Params, origin Word256, txid []byte) *VM {
|
func NewVM(appState AppState, params Params, origin Word256, txid []byte) *VM {
|
||||||
@ -73,7 +72,6 @@ func NewVM(appState AppState, params Params, origin Word256, txid []byte) *VM {
|
|||||||
origin: origin,
|
origin: origin,
|
||||||
callDepth: 0,
|
callDepth: 0,
|
||||||
txid: txid,
|
txid: txid,
|
||||||
doug: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,17 +81,8 @@ func (vm *VM) SetFireable(evc events.Fireable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// to allow calls to native DougContracts (off by default)
|
// to allow calls to native DougContracts (off by default)
|
||||||
func (vm *VM) EnableDoug() {
|
func (vm *VM) EnableSNatives() {
|
||||||
vm.doug = true
|
vm.snative = true
|
||||||
vm.snativeContracts = map[Word256]SNativeContract{
|
|
||||||
RightPadWord256([]byte("hasBasePerm")): vm.hasBasePerm,
|
|
||||||
RightPadWord256([]byte("setBasePerm")): vm.setBasePerm,
|
|
||||||
RightPadWord256([]byte("unsetBasePerm")): vm.unsetBasePerm,
|
|
||||||
RightPadWord256([]byte("setGlobalPerm")): vm.setGlobalPerm,
|
|
||||||
RightPadWord256([]byte("hasRole")): vm.hasRole,
|
|
||||||
RightPadWord256([]byte("addRole")): vm.addRole,
|
|
||||||
RightPadWord256([]byte("rmRole")): vm.rmRole,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// run permission checks before call and create
|
// run permission checks before call and create
|
||||||
@ -757,9 +746,8 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
|
|||||||
if nativeContract := nativeContracts[addr]; nativeContract != nil {
|
if nativeContract := nativeContracts[addr]; nativeContract != nil {
|
||||||
// Native contract
|
// Native contract
|
||||||
ret, err = nativeContract(args, &gasLimit)
|
ret, err = nativeContract(args, &gasLimit)
|
||||||
} else if snativeContract := vm.snativeContracts[addr]; vm.doug && snativeContract != nil {
|
} else if snativeContract := vm.SNativeContract(addr); vm.snative && snativeContract != nil {
|
||||||
// This is Doug and we're calling a snative contract
|
// Secure native contract (with access to chain state)
|
||||||
// TODO: Doug contract should have all permissions
|
|
||||||
ret, err = snativeContract(callee, args)
|
ret, err = snativeContract(callee, args)
|
||||||
} else {
|
} else {
|
||||||
// EVM contract
|
// EVM contract
|
||||||
|
Loading…
x
Reference in New Issue
Block a user