config: allow configuring free gas depending on height

And update default mainnet/testnet settings. Follow neo-project/neo#1888 and
neo-project/neo-node#656.
This commit is contained in:
Roman Khimov 2020-09-08 10:24:08 +03:00
parent 75ed6c8c08
commit 5b05081525
6 changed files with 52 additions and 9 deletions

View file

@ -32,7 +32,7 @@ ProtocolConfiguration:
RegisterTransaction: 10000
VerifyBlocks: true
VerifyTransactions: false
FreeGasLimit: 10.0
FreeGasLimit: {0: 10.0, 6200000: 50.0}
MaxTransactionsPerBlock: 500
MaxFreeTransactionsPerBlock: 20
MaxFreeTransactionSize: 1024

View file

@ -32,7 +32,7 @@ ProtocolConfiguration:
RegisterTransaction: 100
VerifyBlocks: true
VerifyTransactions: false
FreeGasLimit: 10.0
FreeGasLimit: {0: 10.0, 4818000: 50.0}
MaxTransactionsPerBlock: 500
MaxFreeTransactionsPerBlock: 20
MaxFreeTransactionSize: 1024

View file

@ -26,10 +26,12 @@ type (
// transactions exceeding the MaxFreeTransactionSize.
FeePerExtraByte float64 `yaml:"FeePerExtraByte"`
// FreeGasLimit is an amount of GAS which can be spent for free.
FreeGasLimit util.Fixed8 `yaml:"FreeGasLimit"`
LowPriorityThreshold float64 `yaml:"LowPriorityThreshold"`
Magic NetMode `yaml:"Magic"`
MaxTransactionsPerBlock int `yaml:"MaxTransactionsPerBlock"`
// It can change over time, thus it's a map of block height to the
// respective GAS limit.
FreeGasLimit map[uint32]util.Fixed8 `yaml:"FreeGasLimit"`
LowPriorityThreshold float64 `yaml:"LowPriorityThreshold"`
Magic NetMode `yaml:"Magic"`
MaxTransactionsPerBlock int `yaml:"MaxTransactionsPerBlock"`
// Maximum size of low priority transaction in bytes.
MaxFreeTransactionSize int `yaml:"MaxFreeTransactionSize"`
// Maximum number of low priority transactions accepted into block.
@ -61,6 +63,20 @@ type (
NetMode uint32
)
// GetFreeGas returns FreeGasLimit value for given block height.
func (p *ProtocolConfiguration) GetFreeGas(block uint32) util.Fixed8 {
var gas util.Fixed8
var height uint32
for h, g := range p.FreeGasLimit {
if h > block || h < height {
continue
}
gas = g
height = h
}
return gas
}
// String implements the stringer interface.
func (n NetMode) String() string {
switch n {

View file

@ -0,0 +1,25 @@
package config
import (
"testing"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/require"
)
func TestGetFreeGas(t *testing.T) {
fixed10 := util.Fixed8FromInt64(10)
fixed50 := util.Fixed8FromInt64(50)
p := ProtocolConfiguration{
FreeGasLimit: map[uint32]util.Fixed8{
0: fixed10,
6200000: fixed50,
},
}
require.Equal(t, fixed10, p.GetFreeGas(0))
require.Equal(t, fixed10, p.GetFreeGas(1000))
require.Equal(t, fixed10, p.GetFreeGas(1000000))
require.Equal(t, fixed10, p.GetFreeGas(6100000))
require.Equal(t, fixed50, p.GetFreeGas(6200000))
require.Equal(t, fixed50, p.GetFreeGas(7000000))
}

View file

@ -792,8 +792,9 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
v.SetCheckedHash(tx.VerificationHash().BytesBE())
v.LoadScript(t.Script)
v.SetPriceGetter(getPrice)
if bc.config.FreeGasLimit > 0 {
v.SetGasLimit(bc.config.FreeGasLimit + t.Gas)
gasLimit := bc.config.GetFreeGas(block.Index)
if gasLimit > 0 {
v.SetGasLimit(gasLimit + t.Gas)
}
err := v.Run()

View file

@ -605,7 +605,8 @@ func (ic *interopContext) contractMigrate(v *vm.VM) error {
v := ic.bc.GetTestVM(nil)
w := io.NewBufBinWriter()
emit.AppCallWithOperationAndArgs(w.BinWriter, hash, "decimals")
v.SetGasLimit(ic.bc.GetConfig().FreeGasLimit)
conf := ic.bc.GetConfig()
v.SetGasLimit(conf.GetFreeGas(ic.bc.BlockHeight() + 1)) // BlockHeight() is already persisted, so it's either a new block or test invocation.
v.Load(w.Bytes())
if err := v.Run(); err == nil && v.Estack().Len() == 1 {
res := v.Estack().Pop().Item().ToContractParameter(map[vm.StackItem]bool{})