Browse Source

fire events on snative and allow from CallTx

pull/102/head
Ethan Buchman 9 years ago
committed by Jae Kwon
parent
commit
b11012026d
4 changed files with 42 additions and 16 deletions
  1. +6
    -0
      permission/types/permissions.go
  2. +14
    -4
      state/execution.go
  3. +2
    -2
      vm/snative.go
  4. +20
    -10
      vm/vm.go

+ 6
- 0
permission/types/permissions.go View File

@ -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{


+ 14
- 4
state/execution.go View File

@ -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)


+ 2
- 2
vm/snative.go View File

@ -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


+ 20
- 10
vm/vm.go View File

@ -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)
}


Loading…
Cancel
Save