mirror of
https://github.com/fluencelabs/tendermint
synced 2025-08-01 04:31:57 +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 {
|
func (p *BasePermissions) Copy() *BasePermissions {
|
||||||
|
if p == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return &BasePermissions{
|
return &BasePermissions{
|
||||||
Perms: p.Perms,
|
Perms: p.Perms,
|
||||||
SetBit: p.SetBit,
|
SetBit: p.SetBit,
|
||||||
@@ -140,6 +143,9 @@ func (aP *AccountPermissions) RmRole(role string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (aP *AccountPermissions) Copy() *AccountPermissions {
|
func (aP *AccountPermissions) Copy() *AccountPermissions {
|
||||||
|
if aP == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
r := make([]string, len(aP.Roles))
|
r := make([]string, len(aP.Roles))
|
||||||
copy(r, aP.Roles)
|
copy(r, aP.Roles)
|
||||||
return &AccountPermissions{
|
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
|
// 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
|
// 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
|
// 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)
|
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
|
// get or create callee
|
||||||
// this transaction is creating a new contract.
|
|
||||||
if !createAccount {
|
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 outAcc == nil || len(outAcc.Code) == 0 {
|
||||||
// if you call an account that doesn't exist
|
// if you call an account that doesn't exist
|
||||||
// or an account with no code then we take fees (sorry pal)
|
// 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))
|
log.Debug(Fmt("Calling contract %X with code %X", callee.Address, callee.Code))
|
||||||
} else {
|
} else {
|
||||||
callee = txCache.CreateAccount(caller)
|
callee = txCache.CreateAccount(caller)
|
||||||
|
txCache.UpdateAccount(callee)
|
||||||
log.Debug(Fmt("Created new account %X", callee.Address))
|
log.Debug(Fmt("Created new account %X", callee.Address))
|
||||||
code = tx.Data
|
code = tx.Data
|
||||||
}
|
}
|
||||||
log.Debug(Fmt("Code for this contract: %X", code))
|
log.Debug(Fmt("Code for this contract: %X", code))
|
||||||
|
|
||||||
txCache.UpdateAccount(caller) // because we adjusted by input above, and bumped nonce maybe.
|
txCache.UpdateAccount(caller) // because we bumped nonce
|
||||||
txCache.UpdateAccount(callee) // because we adjusted by input above.
|
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 := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(_s.ChainID, tx))
|
||||||
vmach.SetFireable(evc)
|
vmach.SetFireable(evc)
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ const (
|
|||||||
TopSNativePermission ptypes.PermFlag = FirstSNativePerm << (NumSNativePermissions - 1)
|
TopSNativePermission ptypes.PermFlag = FirstSNativePerm << (NumSNativePermissions - 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
var registeredSNativeContracts = map[Word256]ptypes.PermFlag{
|
var RegisteredSNativeContracts = map[Word256]ptypes.PermFlag{
|
||||||
LeftPadWord256([]byte("hasBasePerm")): HasBasePerm,
|
LeftPadWord256([]byte("hasBasePerm")): HasBasePerm,
|
||||||
LeftPadWord256([]byte("setBasePerm")): SetBasePerm,
|
LeftPadWord256([]byte("setBasePerm")): SetBasePerm,
|
||||||
LeftPadWord256([]byte("unsetBasePerm")): UnsetBasePerm,
|
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)
|
type SNativeContract func(acc *Account, input []byte) (output []byte, err error)
|
||||||
|
|
||||||
func (vm *VM) SNativeContract(name Word256) SNativeContract {
|
func (vm *VM) SNativeContract(name Word256) SNativeContract {
|
||||||
flag := registeredSNativeContracts[name]
|
flag := RegisteredSNativeContracts[name]
|
||||||
switch flag {
|
switch flag {
|
||||||
case HasBasePerm:
|
case HasBasePerm:
|
||||||
return vm.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 {
|
if err = transfer(caller, callee, value); err != nil {
|
||||||
*exception = err.Error()
|
*exception = err.Error()
|
||||||
return
|
return
|
||||||
@@ -746,9 +757,6 @@ 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.SNativeContract(addr); vm.snative && snativeContract != nil {
|
|
||||||
// Secure native contract (with access to chain state)
|
|
||||||
ret, err = snativeContract(callee, args)
|
|
||||||
} else {
|
} else {
|
||||||
// EVM contract
|
// EVM contract
|
||||||
if ok = useGas(gas, GasGetAccount); !ok {
|
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)
|
ret, err = vm.Call(callee, callee, acc.Code, args, value, gas)
|
||||||
} else {
|
} else {
|
||||||
if acc == nil {
|
if acc == nil {
|
||||||
// if we have not seen the account before, create it
|
if _, ok := RegisteredSNativeContracts[addr]; vm.snative && ok {
|
||||||
// so we can send funds
|
acc = &Account{Address: addr}
|
||||||
if vm.perms && !vm.HasPermission(caller, ptypes.CreateAccount) {
|
} else {
|
||||||
return nil, ErrPermission{"create_account"}
|
// if we have not seen the account before, create it
|
||||||
}
|
// so we can send funds
|
||||||
acc = &Account{
|
if vm.perms && !vm.HasPermission(caller, ptypes.CreateAccount) {
|
||||||
Address: addr,
|
return nil, ErrPermission{"create_account"}
|
||||||
|
}
|
||||||
|
acc = &Account{Address: addr}
|
||||||
}
|
}
|
||||||
vm.appState.UpdateAccount(acc)
|
vm.appState.UpdateAccount(acc)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user