mirror of
https://github.com/fluencelabs/tendermint
synced 2025-07-31 04:01:55 +00:00
fire events on snative and allow from CallTx
This commit is contained in:
@@ -79,6 +79,9 @@ func (p *BasePermissions) Unset(ty PermFlag) error {
|
||||
}
|
||||
|
||||
func (p *BasePermissions) Copy() *BasePermissions {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
return &BasePermissions{
|
||||
Perms: p.Perms,
|
||||
SetBit: p.SetBit,
|
||||
@@ -140,6 +143,9 @@ func (aP *AccountPermissions) RmRole(role string) bool {
|
||||
}
|
||||
|
||||
func (aP *AccountPermissions) Copy() *AccountPermissions {
|
||||
if aP == nil {
|
||||
return nil
|
||||
}
|
||||
r := make([]string, len(aP.Roles))
|
||||
copy(r, aP.Roles)
|
||||
return &AccountPermissions{
|
||||
|
@@ -405,6 +405,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
||||
// this may be nil if we are still in mempool and contract was created in same block as this tx
|
||||
// but that's fine, because the account will be created properly when the create tx runs in the block
|
||||
// and then this won't return nil. otherwise, we take their fee
|
||||
// it may also be nil if its an snative (not a "real" account)
|
||||
outAcc = blockCache.GetAccount(tx.Address)
|
||||
}
|
||||
|
||||
@@ -431,9 +432,16 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
||||
}
|
||||
)
|
||||
|
||||
// Maybe create a new callee account if
|
||||
// this transaction is creating a new contract.
|
||||
// get or create callee
|
||||
if !createAccount {
|
||||
if outAcc == nil {
|
||||
// check if its an snative
|
||||
if _, ok := vm.RegisteredSNativeContracts[LeftPadWord256(tx.Address)]; ok {
|
||||
// set the outAcc (simply a placeholder until we reach the call)
|
||||
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)
|
||||
@@ -456,13 +464,15 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
||||
log.Debug(Fmt("Calling contract %X with code %X", callee.Address, callee.Code))
|
||||
} else {
|
||||
callee = txCache.CreateAccount(caller)
|
||||
txCache.UpdateAccount(callee)
|
||||
log.Debug(Fmt("Created new account %X", callee.Address))
|
||||
code = tx.Data
|
||||
}
|
||||
log.Debug(Fmt("Code for this contract: %X", code))
|
||||
|
||||
txCache.UpdateAccount(caller) // because we adjusted by input above, and bumped nonce maybe.
|
||||
txCache.UpdateAccount(callee) // because we adjusted by input above.
|
||||
txCache.UpdateAccount(caller) // because we bumped nonce
|
||||
txCache.UpdateAccount(callee) // so the txCache knows about the callee and the transfer takes effect
|
||||
|
||||
vmach := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(_s.ChainID, tx))
|
||||
vmach.SetFireable(evc)
|
||||
|
||||
|
@@ -45,7 +45,7 @@ const (
|
||||
TopSNativePermission ptypes.PermFlag = FirstSNativePerm << (NumSNativePermissions - 1)
|
||||
)
|
||||
|
||||
var registeredSNativeContracts = map[Word256]ptypes.PermFlag{
|
||||
var RegisteredSNativeContracts = map[Word256]ptypes.PermFlag{
|
||||
LeftPadWord256([]byte("hasBasePerm")): HasBasePerm,
|
||||
LeftPadWord256([]byte("setBasePerm")): SetBasePerm,
|
||||
LeftPadWord256([]byte("unsetBasePerm")): UnsetBasePerm,
|
||||
@@ -60,7 +60,7 @@ var registeredSNativeContracts = map[Word256]ptypes.PermFlag{
|
||||
type SNativeContract func(acc *Account, input []byte) (output []byte, err error)
|
||||
|
||||
func (vm *VM) SNativeContract(name Word256) SNativeContract {
|
||||
flag := registeredSNativeContracts[name]
|
||||
flag := RegisteredSNativeContracts[name]
|
||||
switch flag {
|
||||
case HasBasePerm:
|
||||
return vm.hasBasePerm
|
||||
|
30
vm/vm.go
30
vm/vm.go
@@ -117,6 +117,17 @@ func (vm *VM) Call(caller, callee *Account, code, input []byte, value int64, gas
|
||||
}
|
||||
}()
|
||||
|
||||
// if code is empty, callee may be snative contract
|
||||
if vm.snative && len(code) == 0 {
|
||||
if snativeContract := vm.SNativeContract(callee.Address); snativeContract != nil {
|
||||
output, err = snativeContract(caller, input)
|
||||
if err != nil {
|
||||
*exception = err.Error()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = transfer(caller, callee, value); err != nil {
|
||||
*exception = err.Error()
|
||||
return
|
||||
@@ -746,9 +757,6 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
|
||||
if nativeContract := nativeContracts[addr]; nativeContract != nil {
|
||||
// Native contract
|
||||
ret, err = nativeContract(args, &gasLimit)
|
||||
} else if snativeContract := vm.SNativeContract(addr); vm.snative && snativeContract != nil {
|
||||
// Secure native contract (with access to chain state)
|
||||
ret, err = snativeContract(callee, args)
|
||||
} else {
|
||||
// EVM contract
|
||||
if ok = useGas(gas, GasGetAccount); !ok {
|
||||
@@ -766,13 +774,15 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
|
||||
ret, err = vm.Call(callee, callee, acc.Code, args, value, gas)
|
||||
} else {
|
||||
if acc == nil {
|
||||
// if we have not seen the account before, create it
|
||||
// so we can send funds
|
||||
if vm.perms && !vm.HasPermission(caller, ptypes.CreateAccount) {
|
||||
return nil, ErrPermission{"create_account"}
|
||||
}
|
||||
acc = &Account{
|
||||
Address: addr,
|
||||
if _, ok := RegisteredSNativeContracts[addr]; vm.snative && ok {
|
||||
acc = &Account{Address: addr}
|
||||
} else {
|
||||
// if we have not seen the account before, create it
|
||||
// so we can send funds
|
||||
if vm.perms && !vm.HasPermission(caller, ptypes.CreateAccount) {
|
||||
return nil, ErrPermission{"create_account"}
|
||||
}
|
||||
acc = &Account{Address: addr}
|
||||
}
|
||||
vm.appState.UpdateAccount(acc)
|
||||
}
|
||||
|
Reference in New Issue
Block a user