Skip to content

Commit

Permalink
Add refresh gas table (DNAProject#410)
Browse files Browse the repository at this point in the history
  • Loading branch information
tanZiWen authored and laizy committed Jun 25, 2018
1 parent b1275c9 commit 5bc1bfe
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 15 deletions.
2 changes: 1 addition & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ var (
TransactionGasLimitFlag = cli.Uint64Flag{
Name: "gaslimit",
Usage: "Using to specifies the gas limit of the transaction. The gas limit of the transaction cannot be less than the minimum gas limit set by the node's transaction pool, otherwise the transaction will be rejected. Gasprice * gaslimit is actual ONG costs.",
Value: neovm.TRANSACTION_GAS,
Value: neovm.MIN_TRANSACTION_GAS,
}

//Asset setting
Expand Down
4 changes: 4 additions & 0 deletions core/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/ontio/ontology/smartcontract/service/native/governance"
"github.com/ontio/ontology/smartcontract/service/native/ont"
nutils "github.com/ontio/ontology/smartcontract/service/native/utils"
"github.com/ontio/ontology/smartcontract/service/neovm"
)

const (
Expand Down Expand Up @@ -180,6 +181,9 @@ func newParamInit() *types.Transaction {
for k, v := range INIT_PARAM {
params.SetParam(&global_params.Param{k, v})
}
for k, v := range neovm.GAS_TABLE {
params.SetParam(&global_params.Param{k, string(v)})
}
bf := new(bytes.Buffer)
params.Serialize(bf)

Expand Down
17 changes: 15 additions & 2 deletions core/store/ledgerstore/ledger_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,18 @@ func (this *LedgerStoreImp) saveBlockToStateStore(block *types.Block) error {

stateBatch := this.stateStore.NewStateBatch()

if block.Header.Height != 0 {
config := &smartcontract.Config{
Time: block.Header.Timestamp,
Height: block.Header.Height,
Tx: &types.Transaction{},
}

if err := refreshGlobalParam(config, storage.NewCloneCache(this.stateStore.NewStateBatch()), this); err != nil {
return err
}
}

for _, tx := range block.Transactions {
err := this.handleTransaction(stateBatch, block, tx)
if err != nil {
Expand Down Expand Up @@ -791,8 +803,9 @@ func (this *LedgerStoreImp) PreExecuteContract(tx *types.Transaction) (*sstate.P
return nil, err
}
gasCost := math.MaxUint64 - sc.Gas
if gasCost < neovm.TRANSACTION_GAS {
gasCost = neovm.TRANSACTION_GAS
mixGas := neovm.MIN_TRANSACTION_GAS
if gasCost < mixGas {
gasCost = mixGas
}
if err != nil {
return &sstate.PreExecResult{State: event.CONTRACT_STATE_FAIL, Gas: gasCost, Result: nil}, err
Expand Down
49 changes: 47 additions & 2 deletions core/store/ledgerstore/tx_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"bytes"
"fmt"
"math"
"strconv"

"github.com/ontio/ontology/common"
"github.com/ontio/ontology/common/config"
Expand All @@ -35,6 +36,7 @@ import (
"github.com/ontio/ontology/core/types"
"github.com/ontio/ontology/smartcontract"
"github.com/ontio/ontology/smartcontract/event"
"github.com/ontio/ontology/smartcontract/service/native/global_params"
ninit "github.com/ontio/ontology/smartcontract/service/native/init"
"github.com/ontio/ontology/smartcontract/service/native/ont"
"github.com/ontio/ontology/smartcontract/service/native/utils"
Expand Down Expand Up @@ -118,6 +120,7 @@ func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, stateBa
}

cache := storage.NewCloneCache(stateBatch)

//init smart contract info
sc := smartcontract.SmartContract{
Config: config,
Expand All @@ -140,8 +143,9 @@ func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, stateBa
var notifies []*event.NotifyEventInfo
if isCharge {
totalGas := tx.GasLimit - sc.Gas
if totalGas < neovm.TRANSACTION_GAS {
totalGas = neovm.TRANSACTION_GAS
mixGas := neovm.MIN_TRANSACTION_GAS
if totalGas < mixGas {
totalGas = mixGas
}
notifies, err = costGas(tx.Payer, gas, config, sc.CloneCache, store)
if err != nil {
Expand Down Expand Up @@ -212,6 +216,47 @@ func costGas(payer common.Address, gas uint64, config *smartcontract.Config,
return sc.Notifications, nil
}

func refreshGlobalParam(config *smartcontract.Config, cache *storage.CloneCache, store store.LedgerStore) error {
bf := new(bytes.Buffer)
if err := utils.WriteVarUint(bf, uint64(len(neovm.GAS_TABLE_KEYS))); err != nil {
return fmt.Errorf("write gas_table_keys length error:%s", err)
}
for _, value := range neovm.GAS_TABLE_KEYS {
if err := serialization.WriteString(bf, value); err != nil {
return fmt.Errorf("serialize param name error:%s", value)
}
}

sc := smartcontract.SmartContract{
Config: config,
CloneCache: cache,
Store: store,
Gas: math.MaxUint64,
}

service, _ := sc.NewNativeService()
result, err := service.NativeCall(utils.ParamContractAddress, "getGlobalParam", bf.Bytes())
if err != nil {
return err
}
params := new(global_params.Params)
if err := params.Deserialize(bytes.NewBuffer(result.([]byte))); err != nil {
fmt.Errorf("deserialize global params error:%s", err)
}

for k, _ := range neovm.GAS_TABLE {
n, ps := params.GetParam(k)
if n != -1 && ps.Value != "" {
pu, err := strconv.ParseUint(ps.Value, 10, 64)
if err != nil {
return fmt.Errorf("failed to parse uint %v", err)
}
neovm.GAS_TABLE[k] = pu
}
}
return nil
}

func getBalance(stateBatch *statestore.StateBatch, address, contract common.Address) (uint64, error) {
bl, err := stateBatch.TryGet(scommon.ST_STORAGE, append(contract[:], address[:]...))
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func GetGlobalParam(native *native.NativeService) ([]byte, error) {
if index, value := storageParams.GetParam(paramName); index >= 0 {
params.SetParam(value)
} else {
return utils.BYTE_FALSE, errors.NewErr(fmt.Sprintf("get param, param %v doesn't exist!", paramName))
params.SetParam(&Param{Key: paramName, Value: ""})
}
}
err = params.Serialize(result)
Expand Down
28 changes: 24 additions & 4 deletions smartcontract/service/neovm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ package neovm

var (
//Gas Limit
TRANSACTION_GAS uint64 = 30000 // Per transaction base cost.
MIN_TRANSACTION_GAS uint64 = 20000 // Per transaction base cost.
BLOCKCHAIN_GETHEADER_GAS uint64 = 100
BLOCKCHAIN_GETBLOCK_GAS uint64 = 200
BLOCKCHAIN_GETTRANSACTION_GAS uint64 = 100
BLOCKCHAIN_GETCONTRACT_GAS uint64 = 100
CONTRACT_CREATE_GAS uint64 = 10000000
CONTRACT_MIGRATE_GAS uint64 = 10000000
CONTRACT_CREATE_GAS uint64 = 20000000
CONTRACT_MIGRATE_GAS uint64 = 20000000
NATIVE_INVOKE_GAS uint64 = 10000
STORAGE_GET_GAS uint64 = 100
STORAGE_PUT_GAS uint64 = 1000
Expand All @@ -42,6 +42,7 @@ var (

METHOD_LENGTH_LIMIT int = 1024
MAX_STACK_SIZE int = 1024
VM_STEP_LIMIT int = 400000

// API Name
ATTRIBUTE_GETUSAGE_NAME = "Ontology.Attribute.GetUsage"
Expand Down Expand Up @@ -126,5 +127,24 @@ var (
HASH256_NAME: HASH256_GAS,
}

VM_STEP_LIMIT = 400000
GAS_TABLE_KEYS = []string{
BLOCKCHAIN_GETHEADER_NAME,
BLOCKCHAIN_GETBLOCK_NAME,
BLOCKCHAIN_GETTRANSACTION_NAME,
BLOCKCHAIN_GETCONTRACT_NAME,
CONTRACT_CREATE_NAME,
CONTRACT_MIGRATE_NAME,
STORAGE_GET_NAME,
STORAGE_PUT_NAME,
STORAGE_DELETE_NAME,
RUNTIME_CHECKWITNESS_NAME,
NATIVE_INVOKE_NAME,
APPCALL_NAME,
APPCALL_NAME,
TAILCALL_NAME,
SHA1_NAME,
SHA256_NAME,
HASH160_NAME,
HASH256_NAME,
}
)
4 changes: 2 additions & 2 deletions smartcontract/service/neovm/gas_cost.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import (
)

func StoreGasCost(engine *vm.ExecutionEngine) (uint64, error) {
key, err := vm.PeekNByteArray(0, engine)
key, err := vm.PeekNByteArray(1, engine)
if err != nil {
return 0, err
}
value, err := vm.PeekNByteArray(1, engine)
value, err := vm.PeekNByteArray(2, engine)
if err != nil {
return 0, err
}
Expand Down
12 changes: 9 additions & 3 deletions smartcontract/service/neovm/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import (

// StoragePut put smart contract storage item to cache
func StoragePut(service *NeoVmService, engine *vm.ExecutionEngine) error {
if vm.EvaluationStackCount(engine) < 3 {
return errors.NewErr("[Context] Too few input parameters ")
}
context, err := getContext(engine)
if err != nil {
return errors.NewDetailErr(err, errors.ErrNoCode, "[StoragePut] get pop context error!")
Expand Down Expand Up @@ -60,6 +63,9 @@ func StoragePut(service *NeoVmService, engine *vm.ExecutionEngine) error {

// StorageDelete delete smart contract storage item from cache
func StorageDelete(service *NeoVmService, engine *vm.ExecutionEngine) error {
if vm.EvaluationStackCount(engine) < 2 {
return errors.NewErr("[Context] Too few input parameters ")
}
context, err := getContext(engine)
if err != nil {
return errors.NewDetailErr(err, errors.ErrNoCode, "[StorageDelete] get pop context error!")
Expand All @@ -81,6 +87,9 @@ func StorageDelete(service *NeoVmService, engine *vm.ExecutionEngine) error {

// StorageGet push smart contract storage item from cache to vm stack
func StorageGet(service *NeoVmService, engine *vm.ExecutionEngine) error {
if vm.EvaluationStackCount(engine) < 2 {
return errors.NewErr("[Context] Too few input parameters ")
}
context, err := getContext(engine)
if err != nil {
return errors.NewDetailErr(err, errors.ErrNoCode, "[StorageGet] get pop context error!")
Expand Down Expand Up @@ -124,9 +133,6 @@ func checkStorageContext(service *NeoVmService, context *StorageContext) error {
}

func getContext(engine *vm.ExecutionEngine) (*StorageContext, error) {
if vm.EvaluationStackCount(engine) < 2 {
return nil, errors.NewErr("[Context] Too few input parameters ")
}
opInterface, err := vm.PopInteropInterface(engine)
if err != nil {
return nil, err
Expand Down

0 comments on commit 5bc1bfe

Please sign in to comment.