Skip to content

Commit

Permalink
optimize gas table excess (ontio#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
laizy committed Mar 29, 2019
1 parent a37a720 commit e5d335c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 34 deletions.
16 changes: 12 additions & 4 deletions core/store/ledgerstore/ledger_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,11 +629,19 @@ func (this *LedgerStoreImp) executeBlock(block *types.Block) (result store.Execu
return
}
}
gasTable := make(map[string]uint64)
neovm.GAS_TABLE.Range(func(k, value interface{}) bool {
key := k.(string)
val := value.(uint64)
gasTable[key] = val

return true
})

cache := storage.NewCacheDB(overlay)
for _, tx := range block.Transactions {
cache.Reset()
notify, e := this.handleTransaction(overlay, cache, block, tx)
notify, e := this.handleTransaction(overlay, cache, gasTable, block, tx)
if e != nil {
err = e
return
Expand Down Expand Up @@ -845,20 +853,20 @@ func (this *LedgerStoreImp) saveBlock(block *types.Block, stateMerkleRoot common
return this.submitBlock(block, result)
}

func (this *LedgerStoreImp) handleTransaction(overlay *overlaydb.OverlayDB, cache *storage.CacheDB, block *types.Block, tx *types.Transaction) (*event.ExecuteNotify, error) {
func (this *LedgerStoreImp) handleTransaction(overlay *overlaydb.OverlayDB, cache *storage.CacheDB, gasTable map[string]uint64, block *types.Block, tx *types.Transaction) (*event.ExecuteNotify, error) {
txHash := tx.Hash()
notify := &event.ExecuteNotify{TxHash: txHash, State: event.CONTRACT_STATE_FAIL}
switch tx.TxType {
case types.Deploy:
err := this.stateStore.HandleDeployTransaction(this, overlay, cache, tx, block, notify)
err := this.stateStore.HandleDeployTransaction(this, overlay, gasTable, cache, tx, block, notify)
if overlay.Error() != nil {
return nil, fmt.Errorf("HandleDeployTransaction tx %s error %s", txHash.ToHexString(), overlay.Error())
}
if err != nil {
log.Debugf("HandleDeployTransaction tx %s error %s", txHash.ToHexString(), err)
}
case types.Invoke:
err := this.stateStore.HandleInvokeTransaction(this, overlay, cache, tx, block, notify)
err := this.stateStore.HandleInvokeTransaction(this, overlay, gasTable, cache, tx, block, notify)
if overlay.Error() != nil {
return nil, fmt.Errorf("HandleInvokeTransaction tx %s error %s", txHash.ToHexString(), overlay.Error())
}
Expand Down
24 changes: 12 additions & 12 deletions core/store/ledgerstore/tx_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import (
)

//HandleDeployTransaction deal with smart contract deploy transaction
func (self *StateStore) HandleDeployTransaction(store store.LedgerStore, overlay *overlaydb.OverlayDB, cache *storage.CacheDB,
func (self *StateStore) HandleDeployTransaction(store store.LedgerStore, overlay *overlaydb.OverlayDB, gasTable map[string]uint64, cache *storage.CacheDB,
tx *types.Transaction, block *types.Block, notify *event.ExecuteNotify) error {
deploy := tx.Payload.(*payload.DeployCode)
var (
Expand All @@ -63,19 +63,19 @@ func (self *StateStore) HandleDeployTransaction(store store.LedgerStore, overlay
Tx: tx,
BlockHash: block.Hash(),
}
createGasPrice, ok := neovm.GAS_TABLE.Load(neovm.CONTRACT_CREATE_NAME)
createGasPrice, ok := gasTable[neovm.CONTRACT_CREATE_NAME]
if !ok {
overlay.SetError(errors.NewErr("[HandleDeployTransaction] get CONTRACT_CREATE_NAME gas failed"))
return nil
}

uintCodePrice, ok := neovm.GAS_TABLE.Load(neovm.UINT_DEPLOY_CODE_LEN_NAME)
uintCodePrice, ok := gasTable[neovm.UINT_DEPLOY_CODE_LEN_NAME]
if !ok {
overlay.SetError(errors.NewErr("[HandleDeployTransaction] get UINT_DEPLOY_CODE_LEN_NAME gas failed"))
return nil
}

gasLimit := createGasPrice.(uint64) + calcGasByCodeLen(len(deploy.Code), uintCodePrice.(uint64))
gasLimit := createGasPrice + calcGasByCodeLen(len(deploy.Code), uintCodePrice)
balance, err := isBalanceSufficient(tx.Payer, cache, config, store, gasLimit*tx.GasPrice)
if err != nil {
if err := costInvalidGas(tx.Payer, balance, config, overlay, store, notify); err != nil {
Expand Down Expand Up @@ -117,7 +117,7 @@ func (self *StateStore) HandleDeployTransaction(store store.LedgerStore, overlay
}

//HandleInvokeTransaction deal with smart contract invoke transaction
func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, overlay *overlaydb.OverlayDB, cache *storage.CacheDB,
func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, overlay *overlaydb.OverlayDB, gasTable map[string]uint64, cache *storage.CacheDB,
tx *types.Transaction, block *types.Block, notify *event.ExecuteNotify) error {
invoke := tx.Payload.(*payload.InvokeCode)
code := invoke.Code
Expand Down Expand Up @@ -146,7 +146,7 @@ func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, overlay

availableGasLimit = tx.GasLimit
if isCharge {
uintCodeGasPrice, ok := neovm.GAS_TABLE.Load(neovm.UINT_INVOKE_CODE_LEN_NAME)
uintCodeGasPrice, ok := gasTable[neovm.UINT_INVOKE_CODE_LEN_NAME]
if !ok {
overlay.SetError(errors.NewErr("[HandleInvokeTransaction] get UINT_INVOKE_CODE_LEN_NAME gas failed"))
return nil
Expand All @@ -166,7 +166,7 @@ func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, overlay
return fmt.Errorf("balance gas: %d less than min gas: %d", oldBalance, minGas)
}

codeLenGasLimit = calcGasByCodeLen(len(invoke.Code), uintCodeGasPrice.(uint64))
codeLenGasLimit = calcGasByCodeLen(len(invoke.Code), uintCodeGasPrice)

if oldBalance < codeLenGasLimit*tx.GasPrice {
if err := costInvalidGas(tx.Payer, oldBalance, config, overlay, store, notify); err != nil {
Expand All @@ -190,10 +190,11 @@ func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, overlay

//init smart contract info
sc := smartcontract.SmartContract{
Config: config,
CacheDB: cache,
Store: store,
Gas: availableGasLimit - codeLenGasLimit,
Config: config,
CacheDB: cache,
Store: store,
GasTable: gasTable,
Gas: availableGasLimit - codeLenGasLimit,
}

//start the smart contract executive function
Expand Down Expand Up @@ -328,7 +329,6 @@ func refreshGlobalParam(config *smartcontract.Config, cache *storage.CacheDB, st
log.Errorf("[refreshGlobalParam] failed to parse uint %v\n", ps.Value)
} else {
neovm.GAS_TABLE.Store(key, pu)

}
}
return true
Expand Down
14 changes: 7 additions & 7 deletions smartcontract/service/neovm/gas_cost.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
vm "github.com/ontio/ontology/vm/neovm"
)

func StoreGasCost(engine *vm.Executor) (uint64, error) {
func StoreGasCost(gasTable map[string]uint64, engine *vm.Executor) (uint64, error) {
key, err := engine.EvalStack.PeekAsBytes(1)
if err != nil {
return 0, err
Expand All @@ -32,20 +32,20 @@ func StoreGasCost(engine *vm.Executor) (uint64, error) {
if err != nil {
return 0, err
}
if putCost, ok := GAS_TABLE.Load(STORAGE_PUT_NAME); ok {
return uint64(((len(key)+len(value)-1)/1024 + 1)) * putCost.(uint64), nil
if putCost, ok := gasTable[STORAGE_PUT_NAME]; ok {
return uint64(((len(key)+len(value)-1)/1024 + 1)) * putCost, nil
} else {
return uint64(0), errors.NewErr("[StoreGasCost] get STORAGE_PUT_NAME gas failed")
}
}

func GasPrice(engine *vm.Executor, name string) (uint64, error) {
func GasPrice(gasTable map[string]uint64, engine *vm.Executor, name string) (uint64, error) {
switch name {
case STORAGE_PUT_NAME:
return StoreGasCost(engine)
return StoreGasCost(gasTable, engine)
default:
if value, ok := GAS_TABLE.Load(name); ok {
return value.(uint64), nil
if value, ok := gasTable[name]; ok {
return value, nil
}
return OPCODE_GAS, nil
}
Expand Down
24 changes: 13 additions & 11 deletions smartcontract/service/neovm/neovm_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ type NeoVmService struct {
ContextRef context.ContextRef
Notifications []*event.NotifyEventInfo
Code []byte
GasTable map[string]uint64
Tx *types.Transaction
Time uint32
Height uint32
Expand All @@ -135,6 +136,7 @@ func (this *NeoVmService) Invoke() (*vmty.VmValue, error) {
}
this.ContextRef.PushContext(&context.Context{ContractAddress: scommon.AddressFromVmCode(this.Code), Code: this.Code})
this.Engine.PushContext(vm.NewExecutionContext(this.Code))
var gasTable [256]uint64
for {
//check the execution step count
if this.PreExec && !this.ContextRef.CheckExecStep() {
Expand All @@ -161,11 +163,16 @@ func (this *NeoVmService) Invoke() (*vmty.VmValue, error) {
return nil, ERR_GAS_INSUFFICIENT
}
} else {

opExec := vm.OpExecList[opCode]
price, err := GasPrice(this.Engine, opExec.Name)
if err != nil {
return nil, err
price := gasTable[opCode]
if price == 0 {
opExec := vm.OpExecList[opCode]
p, err := GasPrice(this.GasTable, this.Engine, opExec.Name)
if err != nil {
return nil, err
}
price = p
// note: this works because the gas fee for opcode is constant
gasTable[opCode] = price
}
if !this.ContextRef.CheckUseGas(price) {
return nil, ERR_GAS_INSUFFICIENT
Expand Down Expand Up @@ -251,12 +258,7 @@ func (this *NeoVmService) SystemCall(engine *vm.Executor) error {
if !ok {
return errors.NewErr(fmt.Sprintf("[SystemCall] service not support: %s", serviceName))
}
//if service.Validator != nil {
// if err := service.Validator(engine); err != nil {
// return errors.NewDetailErr(err, errors.ErrNoCode, "[SystemCall] service validator error!")
// }
//}
price, err := GasPrice(engine, serviceName)
price, err := GasPrice(this.GasTable, engine, serviceName)
if err != nil {
return err
}
Expand Down
2 changes: 2 additions & 0 deletions smartcontract/smart_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type SmartContract struct {
Store store.LedgerStore // ledger store
Config *Config
Notifications []*event.NotifyEventInfo // all execute smart contract event notify info
GasTable map[string]uint64
Gas uint64
ExecStep int
PreExec bool
Expand Down Expand Up @@ -130,6 +131,7 @@ func (this *SmartContract) NewExecuteEngine(code []byte) (context.Engine, error)
Store: this.Store,
CacheDB: this.CacheDB,
ContextRef: this,
GasTable: this.GasTable,
Code: code,
Tx: this.Config.Tx,
Time: this.Config.Time,
Expand Down

0 comments on commit e5d335c

Please sign in to comment.