forked from TrueCloudLab/neoneo-go
core: allow to create hard-fork
This commit is contained in:
parent
d1588115a2
commit
e70bf7d12e
6 changed files with 86 additions and 1 deletions
31
pkg/config/hardfork.go
Normal file
31
pkg/config/hardfork.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package config
|
||||
|
||||
//go:generate stringer -type=Hardfork -linecomment
|
||||
|
||||
// Hardfork represents the application hard-fork identifier.
|
||||
type Hardfork byte
|
||||
|
||||
const (
|
||||
// HF2712FixSyscallFees represents hard-fork introduced in #2469 (ported from
|
||||
// https://github.com/neo-project/neo/pull/2712) changing the prices of
|
||||
// System.Contract.CreateStandardAccount and
|
||||
// System.Contract.CreateMultisigAccount interops.
|
||||
HF2712FixSyscallFees Hardfork = 1 << iota // HF_2712_FixSyscallFees
|
||||
)
|
||||
|
||||
// hardforks holds a map of Hardfork string representation to its type.
|
||||
var hardforks map[string]Hardfork
|
||||
|
||||
func init() {
|
||||
hardforks = make(map[string]Hardfork)
|
||||
for _, hf := range []Hardfork{HF2712FixSyscallFees} {
|
||||
hardforks[hf.String()] = hf
|
||||
}
|
||||
}
|
||||
|
||||
// IsHardforkValid denotes whether the provided string represents a valid
|
||||
// Hardfork name.
|
||||
func IsHardforkValid(s string) bool {
|
||||
_, ok := hardforks[s]
|
||||
return ok
|
||||
}
|
24
pkg/config/hardfork_string.go
Normal file
24
pkg/config/hardfork_string.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Code generated by "stringer -type Hardfork -linecomment ./pkg/config/hardfork.go"; DO NOT EDIT.
|
||||
|
||||
package config
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[HF2712FixSyscallFees-1]
|
||||
}
|
||||
|
||||
const _Hardfork_name = "HF_2712_FixSyscallFees"
|
||||
|
||||
var _Hardfork_index = [...]uint8{0, 22}
|
||||
|
||||
func (i Hardfork) String() string {
|
||||
i -= 1
|
||||
if i >= Hardfork(len(_Hardfork_index)-1) {
|
||||
return "Hardfork(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||
}
|
||||
return _Hardfork_name[_Hardfork_index[i]:_Hardfork_index[i+1]]
|
||||
}
|
|
@ -23,6 +23,9 @@ type (
|
|||
Magic netmode.Magic `yaml:"Magic"`
|
||||
MemPoolSize int `yaml:"MemPoolSize"`
|
||||
|
||||
// Hardforks is a map of hardfork names that enables version-specific application
|
||||
// logic dependent on the specified height.
|
||||
Hardforks map[string]uint32 `yaml:"Hardforks"`
|
||||
// InitialGASSupply is the amount of GAS generated in the genesis block.
|
||||
InitialGASSupply fixedn.Fixed8 `yaml:"InitialGASSupply"`
|
||||
// P2PNotaryRequestPayloadPoolSize specifies the memory pool size for P2PNotaryRequestPayloads.
|
||||
|
@ -94,6 +97,11 @@ func (p *ProtocolConfiguration) Validate() error {
|
|||
return fmt.Errorf("NativeActivations configuration section contains unexpected native contract name: %s", name)
|
||||
}
|
||||
}
|
||||
for name := range p.Hardforks {
|
||||
if !IsHardforkValid(name) {
|
||||
return fmt.Errorf("Hardforks configuration section contains unexpected hardfork: %s", name)
|
||||
}
|
||||
}
|
||||
if p.ValidatorsCount != 0 && len(p.ValidatorsHistory) != 0 {
|
||||
return errors.New("configuration should either have ValidatorsCount or ValidatorsHistory, not both")
|
||||
}
|
||||
|
|
|
@ -100,6 +100,12 @@ func TestProtocolConfigurationValidation(t *testing.T) {
|
|||
ValidatorsHistory: map[uint32]int{0: 4, 100: 4},
|
||||
}
|
||||
require.Error(t, p.Validate())
|
||||
p = &ProtocolConfiguration{
|
||||
Hardforks: map[string]uint32{
|
||||
"HF_Unknown": 123, // Unknown hard-fork.
|
||||
},
|
||||
}
|
||||
require.Error(t, p.Validate())
|
||||
p = &ProtocolConfiguration{
|
||||
StandbyCommittee: []string{
|
||||
"02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2",
|
||||
|
|
|
@ -259,6 +259,10 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L
|
|||
cfg.NativeUpdateHistories = map[string][]uint32{}
|
||||
log.Info("NativeActivations are not set, using default values")
|
||||
}
|
||||
if cfg.Hardforks == nil {
|
||||
cfg.Hardforks = map[string]uint32{}
|
||||
log.Info("Hardforks are not set, using default value")
|
||||
}
|
||||
bc := &Blockchain{
|
||||
config: cfg,
|
||||
dao: dao.NewSimple(s, cfg.StateRootInHeader, cfg.P2PSigExtensions),
|
||||
|
|
|
@ -48,6 +48,7 @@ type Context struct {
|
|||
Chain Ledger
|
||||
Container hash.Hashable
|
||||
Network uint32
|
||||
Hardforks map[string]uint32
|
||||
Natives []Contract
|
||||
Trigger trigger.Type
|
||||
Block *block.Block
|
||||
|
@ -71,9 +72,11 @@ func NewContext(trigger trigger.Type, bc Ledger, d *dao.Simple, baseExecFee, bas
|
|||
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error), natives []Contract,
|
||||
block *block.Block, tx *transaction.Transaction, log *zap.Logger) *Context {
|
||||
dao := d.GetPrivate()
|
||||
cfg := bc.GetConfig()
|
||||
return &Context{
|
||||
Chain: bc,
|
||||
Network: uint32(bc.GetConfig().Magic),
|
||||
Network: uint32(cfg.Magic),
|
||||
Hardforks: cfg.Hardforks,
|
||||
Natives: natives,
|
||||
Trigger: trigger,
|
||||
Block: block,
|
||||
|
@ -368,3 +371,12 @@ func (ic *Context) GetBlock(hash util.Uint256) (*block.Block, error) {
|
|||
}
|
||||
return block, nil
|
||||
}
|
||||
|
||||
// IsHardforkEnabled tells whether specified hard-fork enabled at the current context height.
|
||||
func (ic *Context) IsHardforkEnabled(hf config.Hardfork) bool {
|
||||
height, ok := ic.Hardforks[hf.String()]
|
||||
if ok {
|
||||
return ic.BlockHeight() >= height
|
||||
}
|
||||
return len(ic.Hardforks) == 0 // Enable each hard-fork by default.
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue