diff --git a/config/protocol.mainnet.yml b/config/protocol.mainnet.yml index 65c107194..acf46f8fd 100644 --- a/config/protocol.mainnet.yml +++ b/config/protocol.mainnet.yml @@ -1,6 +1,7 @@ ProtocolConfiguration: Magic: 5195086 MaxTraceableBlocks: 2102400 + InitialGASSupply: 52000000 SecondsPerBlock: 15 MemPoolSize: 50000 StandbyCommittee: diff --git a/config/protocol.testnet.yml b/config/protocol.testnet.yml index 9d6f407b1..0a71ec4e1 100644 --- a/config/protocol.testnet.yml +++ b/config/protocol.testnet.yml @@ -1,6 +1,7 @@ ProtocolConfiguration: Magic: 877933390 MaxTraceableBlocks: 2102400 + InitialGASSupply: 52000000 SecondsPerBlock: 15 MemPoolSize: 50000 StandbyCommittee: diff --git a/pkg/compiler/native_test.go b/pkg/compiler/native_test.go index bf73a1baf..eda0a392a 100644 --- a/pkg/compiler/native_test.go +++ b/pkg/compiler/native_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames" "github.com/nspcc-dev/neo-go/pkg/core/native" @@ -30,7 +31,8 @@ import ( ) func TestContractHashes(t *testing.T) { - cs := native.NewContracts(true, map[string][]uint32{}) + cfg := config.ProtocolConfiguration{P2PSigExtensions: true} + cs := native.NewContracts(cfg) require.Equalf(t, []byte(neo.Hash), cs.NEO.Hash.BytesBE(), "%q", string(cs.NEO.Hash.BytesBE())) require.Equalf(t, []byte(gas.Hash), cs.GAS.Hash.BytesBE(), "%q", string(cs.GAS.Hash.BytesBE())) require.Equalf(t, []byte(oracle.Hash), cs.Oracle.Hash.BytesBE(), "%q", string(cs.Oracle.Hash.BytesBE())) @@ -92,7 +94,8 @@ type nativeTestCase struct { // Here we test that corresponding method does exist, is invoked and correct value is returned. func TestNativeHelpersCompile(t *testing.T) { - cs := native.NewContracts(true, map[string][]uint32{}) + cfg := config.ProtocolConfiguration{P2PSigExtensions: true} + cs := native.NewContracts(cfg) u160 := `interop.Hash160("aaaaaaaaaaaaaaaaaaaa")` u256 := `interop.Hash256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")` pub := `interop.PublicKey("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")` diff --git a/pkg/config/protocol_config.go b/pkg/config/protocol_config.go index 063bd17bb..9c3482933 100644 --- a/pkg/config/protocol_config.go +++ b/pkg/config/protocol_config.go @@ -2,6 +2,7 @@ package config import ( "github.com/nspcc-dev/neo-go/pkg/config/netmode" + "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" ) // ProtocolConfiguration represents the protocol config. @@ -9,6 +10,9 @@ type ( ProtocolConfiguration struct { Magic netmode.Magic `yaml:"Magic"` MemPoolSize int `yaml:"MemPoolSize"` + + // InitialGASSupply is the amount of GAS generated in the genesis block. + InitialGASSupply fixedn.Fixed8 `yaml:"InitialGASSupply"` // P2PNotaryRequestPayloadPoolSize specifies the memory pool size for P2PNotaryRequestPayloads. // It is valid only if P2PSigExtensions are enabled. P2PNotaryRequestPayloadPoolSize int `yaml:"P2PNotaryRequestPayloadPoolSize"` diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index 747c47653..50ceca6f2 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -389,13 +389,14 @@ func TestVerifyBlock(t *testing.T) { require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("good conflicting tx", func(t *testing.T) { + initGAS := srv.Chain.GetConfig().InitialGASSupply tx1 := transaction.New([]byte{byte(opcode.RET)}, 100000) - tx1.NetworkFee = 20_000_000 * native.GASFactor + tx1.NetworkFee = int64(initGAS)/2 + 1 tx1.ValidUntilBlock = 1 addSender(t, tx1) signTx(t, srv.Chain, tx1) tx2 := transaction.New([]byte{byte(opcode.RET)}, 100000) - tx2.NetworkFee = 20_000_000 * native.GASFactor + tx2.NetworkFee = int64(initGAS)/2 + 1 tx2.ValidUntilBlock = 1 addSender(t, tx2) signTx(t, srv.Chain, tx2) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 5a820a967..689ea3be6 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -28,6 +28,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" + "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" @@ -44,6 +45,7 @@ const ( headerBatchCount = 2000 version = "0.1.0" + defaultInitialGAS = 52000000_00000000 defaultMemPoolSize = 50000 defaultP2PNotaryRequestPayloadPoolSize = 1000 defaultMaxBlockSize = 262144 @@ -165,6 +167,10 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L return nil, errors.New("empty logger") } + if cfg.InitialGASSupply <= 0 { + cfg.InitialGASSupply = fixedn.Fixed8(defaultInitialGAS) + log.Info("initial gas supply is not set or wrong, setting default value", zap.String("InitialGASSupply", cfg.InitialGASSupply.String())) + } if cfg.MemPoolSize <= 0 { cfg.MemPoolSize = defaultMemPoolSize log.Info("mempool size is not set or wrong, setting default value", zap.Int("MemPoolSize", cfg.MemPoolSize)) @@ -216,8 +222,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L events: make(chan bcEvent), subCh: make(chan interface{}), unsubCh: make(chan interface{}), - - contracts: *native.NewContracts(cfg.P2PSigExtensions, cfg.NativeUpdateHistories), + contracts: *native.NewContracts(cfg), } bc.stateRoot = stateroot.NewModule(bc, bc.log, bc.dao.Store) diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index 302b9c447..d3a2b7ead 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -1639,7 +1639,7 @@ func TestConfigNativeUpdateHistory(t *testing.T) { cfgPath := path.Join(prefixPath, fmt.Sprintf("protocol.%s.yml", cfgFileSuffix)) cfg, err := config.LoadFile(cfgPath) require.NoError(t, err, fmt.Errorf("failed to load %s", cfgPath)) - natives := native.NewContracts(cfg.ProtocolConfiguration.P2PSigExtensions, map[string][]uint32{}) + natives := native.NewContracts(cfg.ProtocolConfiguration) assert.Equal(t, len(natives.Contracts), len(cfg.ProtocolConfiguration.NativeUpdateHistories), fmt.Errorf("protocol configuration file %s: extra or missing NativeUpdateHistory in NativeActivations section", cfgPath)) diff --git a/pkg/core/native/compatibility_test.go b/pkg/core/native/compatibility_test.go index 40754114d..77c0878d0 100644 --- a/pkg/core/native/compatibility_test.go +++ b/pkg/core/native/compatibility_test.go @@ -4,12 +4,14 @@ import ( "testing" "unicode" + "github.com/nspcc-dev/neo-go/pkg/config" "github.com/stretchr/testify/require" ) // "C" and "O" can easily be typed by accident. func TestNamesASCII(t *testing.T) { - cs := NewContracts(true, map[string][]uint32{}) + cfg := config.ProtocolConfiguration{P2PSigExtensions: true} + cs := NewContracts(cfg) for _, c := range cs.Contracts { require.True(t, isASCII(c.Metadata().Name)) for _, m := range c.Metadata().Methods { diff --git a/pkg/core/native/contract.go b/pkg/core/native/contract.go index 74cacaf42..a953827eb 100644 --- a/pkg/core/native/contract.go +++ b/pkg/core/native/contract.go @@ -3,6 +3,7 @@ package native import ( "strings" + "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames" "github.com/nspcc-dev/neo-go/pkg/io" @@ -55,7 +56,7 @@ func (cs *Contracts) ByName(name string) interop.Contract { // NewContracts returns new set of native contracts with new GAS, NEO, Policy, Oracle, // Designate and (optional) Notary contracts. -func NewContracts(p2pSigExtensionsEnabled bool, nativeUpdateHistories map[string][]uint32) *Contracts { +func NewContracts(cfg config.ProtocolConfiguration) *Contracts { cs := new(Contracts) mgmt := newManagement() @@ -74,7 +75,7 @@ func NewContracts(p2pSigExtensionsEnabled bool, nativeUpdateHistories map[string cs.Ledger = ledger cs.Contracts = append(cs.Contracts, ledger) - gas := newGAS() + gas := newGAS(int64(cfg.InitialGASSupply)) neo := newNEO() neo.GAS = gas gas.NEO = neo @@ -90,7 +91,7 @@ func NewContracts(p2pSigExtensionsEnabled bool, nativeUpdateHistories map[string cs.Policy = policy cs.Contracts = append(cs.Contracts, policy) - desig := newDesignate(p2pSigExtensionsEnabled) + desig := newDesignate(cfg.P2PSigExtensions) desig.NEO = neo cs.Designate = desig cs.Contracts = append(cs.Contracts, desig) @@ -102,7 +103,7 @@ func NewContracts(p2pSigExtensionsEnabled bool, nativeUpdateHistories map[string cs.Oracle = oracle cs.Contracts = append(cs.Contracts, oracle) - if p2pSigExtensionsEnabled { + if cfg.P2PSigExtensions { notary := newNotary() notary.GAS = gas notary.NEO = neo @@ -111,12 +112,13 @@ func NewContracts(p2pSigExtensionsEnabled bool, nativeUpdateHistories map[string cs.Contracts = append(cs.Contracts, notary) } - setDefaultHistory := len(nativeUpdateHistories) == 0 + setDefaultHistory := len(cfg.NativeUpdateHistories) == 0 for _, c := range cs.Contracts { - if setDefaultHistory { - nativeUpdateHistories[c.Metadata().Name] = []uint32{0} + var history = []uint32{0} + if !setDefaultHistory { + history = cfg.NativeUpdateHistories[c.Metadata().Name] } - c.Metadata().NativeContract.UpdateHistory = nativeUpdateHistories[c.Metadata().Name] + c.Metadata().NativeContract.UpdateHistory = history } return cs } diff --git a/pkg/core/native/native_gas.go b/pkg/core/native/native_gas.go index 7167706d1..016f30b44 100644 --- a/pkg/core/native/native_gas.go +++ b/pkg/core/native/native_gas.go @@ -21,17 +21,18 @@ import ( type GAS struct { nep17TokenNative NEO *NEO + + initialSupply int64 } const gasContractID = -6 // GASFactor is a divisor for finding GAS integral value. const GASFactor = NEOTotalSupply -const initialGAS = 30000000 // newGAS returns GAS native contract. -func newGAS() *GAS { - g := &GAS{} +func newGAS(init int64) *GAS { + g := &GAS{initialSupply: init} defer g.UpdateHash() nep17 := newNEP17Native(nativenames.Gas, gasContractID) @@ -109,7 +110,7 @@ func (g *GAS) Initialize(ic *interop.Context) error { if err != nil { return err } - g.mint(ic, h, big.NewInt(initialGAS*GASFactor), false) + g.mint(ic, h, big.NewInt(g.initialSupply), false) return nil } diff --git a/pkg/core/native/nativenames_test.go b/pkg/core/native/nativenames_test.go index 7729d54de..b710f09be 100644 --- a/pkg/core/native/nativenames_test.go +++ b/pkg/core/native/nativenames_test.go @@ -4,13 +4,15 @@ import ( "fmt" "testing" + "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/stretchr/testify/require" ) func TestNativenamesIsValid(t *testing.T) { // test that all native names has been added to IsValid - contracts := NewContracts(true, map[string][]uint32{}) + cfg := config.ProtocolConfiguration{P2PSigExtensions: true} + contracts := NewContracts(cfg) for _, c := range contracts.Contracts { require.True(t, nativenames.IsValid(c.Metadata().Name), fmt.Errorf("add %s to nativenames.IsValid(...)", c)) } diff --git a/scripts/compare-dumps_test.go b/scripts/compare-dumps_test.go index 85a50fc64..726069a2f 100644 --- a/scripts/compare-dumps_test.go +++ b/scripts/compare-dumps_test.go @@ -3,11 +3,12 @@ package main import ( "testing" + "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/stretchr/testify/require" ) func TestCompatibility(t *testing.T) { - cs := native.NewContracts(false, map[string][]uint32{}) + cs := native.NewContracts(config.ProtocolConfiguration{}) require.Equal(t, cs.Ledger.ID, int32(ledgerContractID)) }