diff --git a/params/confp/tconvert/doc.go b/params/confp/tconvert/doc.go index 14877f188cd3..1a63dde4e24b 100644 --- a/params/confp/tconvert/doc.go +++ b/params/confp/tconvert/doc.go @@ -21,6 +21,6 @@ It represents vestigial constructions for converting between chain configuration data types. I believe all functions are used only in the cmd/puppeth package. These functions should be replaced in their occurrences with `convert.Convert` logic instead, -and then this package can +and then this package can die. */ package tconvert diff --git a/params/types/goethereum/goethereum_configurator.go b/params/types/goethereum/goethereum_configurator.go index 8ee9162e3b6c..78c2dfe8f4b8 100644 --- a/params/types/goethereum/goethereum_configurator.go +++ b/params/types/goethereum/goethereum_configurator.go @@ -53,35 +53,35 @@ func setBig(i *big.Int, u *uint64) *big.Int { } func (c *ChainConfig) GetAccountStartNonce() *uint64 { - return internal.One().GetAccountStartNonce() + return internal.GlobalConfigurator().GetAccountStartNonce() } func (c *ChainConfig) SetAccountStartNonce(n *uint64) error { - return internal.One().SetAccountStartNonce(n) + return internal.GlobalConfigurator().SetAccountStartNonce(n) } func (c *ChainConfig) GetMaximumExtraDataSize() *uint64 { - return internal.One().GetMaximumExtraDataSize() + return internal.GlobalConfigurator().GetMaximumExtraDataSize() } func (c *ChainConfig) SetMaximumExtraDataSize(n *uint64) error { - return internal.One().SetMaximumExtraDataSize(n) + return internal.GlobalConfigurator().SetMaximumExtraDataSize(n) } func (c *ChainConfig) GetMinGasLimit() *uint64 { - return internal.One().GetMinGasLimit() + return internal.GlobalConfigurator().GetMinGasLimit() } func (c *ChainConfig) SetMinGasLimit(n *uint64) error { - return internal.One().SetMinGasLimit(n) + return internal.GlobalConfigurator().SetMinGasLimit(n) } func (c *ChainConfig) GetGasLimitBoundDivisor() *uint64 { - return internal.One().GetGasLimitBoundDivisor() + return internal.GlobalConfigurator().GetGasLimitBoundDivisor() } func (c *ChainConfig) SetGasLimitBoundDivisor(n *uint64) error { - return internal.One().SetGasLimitBoundDivisor(n) + return internal.GlobalConfigurator().SetGasLimitBoundDivisor(n) } // GetNetworkID and the following Set/Getters for ChainID too @@ -121,11 +121,11 @@ func (c *ChainConfig) SetChainID(n *big.Int) error { } func (c *ChainConfig) GetMaxCodeSize() *uint64 { - return internal.One().GetMaxCodeSize() + return internal.GlobalConfigurator().GetMaxCodeSize() } func (c *ChainConfig) SetMaxCodeSize(n *uint64) error { - return internal.One().SetMaxCodeSize(n) + return internal.GlobalConfigurator().SetMaxCodeSize(n) } func (c *ChainConfig) GetEIP7Transition() *uint64 { @@ -386,9 +386,6 @@ func (c *ChainConfig) GetForkCanonHashes() map[uint64]common.Hash { } func (c *ChainConfig) GetConsensusEngineType() ctypes.ConsensusEngineT { - if c.Ethash != nil { - return ctypes.ConsensusEngineT_Ethash - } if c.Clique != nil { return ctypes.ConsensusEngineT_Clique } @@ -409,27 +406,27 @@ func (c *ChainConfig) MustSetConsensusEngineType(t ctypes.ConsensusEngineT) erro } func (c *ChainConfig) GetEthashMinimumDifficulty() *big.Int { - return internal.One().GetEthashMinimumDifficulty() + return internal.GlobalConfigurator().GetEthashMinimumDifficulty() } func (c *ChainConfig) SetEthashMinimumDifficulty(i *big.Int) error { - return internal.One().SetEthashMinimumDifficulty(i) + return internal.GlobalConfigurator().SetEthashMinimumDifficulty(i) } func (c *ChainConfig) GetEthashDifficultyBoundDivisor() *big.Int { - return internal.One().GetEthashDifficultyBoundDivisor() + return internal.GlobalConfigurator().GetEthashDifficultyBoundDivisor() } func (c *ChainConfig) SetEthashDifficultyBoundDivisor(i *big.Int) error { - return internal.One().SetEthashDifficultyBoundDivisor(i) + return internal.GlobalConfigurator().SetEthashDifficultyBoundDivisor(i) } func (c *ChainConfig) GetEthashDurationLimit() *big.Int { - return internal.One().GetEthashDurationLimit() + return internal.GlobalConfigurator().GetEthashDurationLimit() } func (c *ChainConfig) SetEthashDurationLimit(i *big.Int) error { - return internal.One().SetEthashDurationLimit(i) + return internal.GlobalConfigurator().SetEthashDurationLimit(i) } // NOTE: Checking for if c.Ethash == nil is a consideration. diff --git a/params/types/internal/vars_configurator.go b/params/types/internal/vars_configurator.go index e18e543b1dea..75f1b866341a 100644 --- a/params/types/internal/vars_configurator.go +++ b/params/types/internal/vars_configurator.go @@ -10,19 +10,21 @@ import ( type GlobalVarsConfigurator struct { } -func One() *GlobalVarsConfigurator { - return &GlobalVarsConfigurator{} +var gc = &GlobalVarsConfigurator{} + +func GlobalConfigurator() *GlobalVarsConfigurator { + return gc } func newU64(u uint64) *uint64 { return &u } -func (g GlobalVarsConfigurator) GetAccountStartNonce() *uint64 { +func (_ GlobalVarsConfigurator) GetAccountStartNonce() *uint64 { return newU64(0) } -func (g GlobalVarsConfigurator) SetAccountStartNonce(n *uint64) error { +func (_ GlobalVarsConfigurator) SetAccountStartNonce(n *uint64) error { if n == nil { return nil } @@ -32,38 +34,38 @@ func (g GlobalVarsConfigurator) SetAccountStartNonce(n *uint64) error { return nil } -func (g GlobalVarsConfigurator) GetMaximumExtraDataSize() *uint64 { +func (_ GlobalVarsConfigurator) GetMaximumExtraDataSize() *uint64 { return newU64(vars.MaximumExtraDataSize) } -func (g GlobalVarsConfigurator) SetMaximumExtraDataSize(n *uint64) error { +func (_ GlobalVarsConfigurator) SetMaximumExtraDataSize(n *uint64) error { vars.MaximumExtraDataSize = *n return nil } -func (g GlobalVarsConfigurator) GetMinGasLimit() *uint64 { +func (_ GlobalVarsConfigurator) GetMinGasLimit() *uint64 { return newU64(vars.MinGasLimit) } -func (g GlobalVarsConfigurator) SetMinGasLimit(n *uint64) error { +func (_ GlobalVarsConfigurator) SetMinGasLimit(n *uint64) error { vars.MinGasLimit = *n return nil } -func (g GlobalVarsConfigurator) GetGasLimitBoundDivisor() *uint64 { +func (_ GlobalVarsConfigurator) GetGasLimitBoundDivisor() *uint64 { return newU64(vars.GasLimitBoundDivisor) } -func (g GlobalVarsConfigurator) SetGasLimitBoundDivisor(n *uint64) error { +func (_ GlobalVarsConfigurator) SetGasLimitBoundDivisor(n *uint64) error { vars.GasLimitBoundDivisor = *n return nil } -func (g GlobalVarsConfigurator) GetMaxCodeSize() *uint64 { +func (_ GlobalVarsConfigurator) GetMaxCodeSize() *uint64 { return newU64(vars.MaxCodeSize) } -func (g GlobalVarsConfigurator) SetMaxCodeSize(n *uint64) error { +func (_ GlobalVarsConfigurator) SetMaxCodeSize(n *uint64) error { if n == nil { return nil } @@ -71,10 +73,10 @@ func (g GlobalVarsConfigurator) SetMaxCodeSize(n *uint64) error { return nil } -func (c GlobalVarsConfigurator) GetEthashMinimumDifficulty() *big.Int { +func (_ GlobalVarsConfigurator) GetEthashMinimumDifficulty() *big.Int { return vars.MinimumDifficulty } -func (c GlobalVarsConfigurator) SetEthashMinimumDifficulty(i *big.Int) error { +func (_ GlobalVarsConfigurator) SetEthashMinimumDifficulty(i *big.Int) error { if i == nil { return ctypes.ErrUnsupportedConfigFatal } @@ -82,11 +84,11 @@ func (c GlobalVarsConfigurator) SetEthashMinimumDifficulty(i *big.Int) error { return nil } -func (c GlobalVarsConfigurator) GetEthashDifficultyBoundDivisor() *big.Int { +func (_ GlobalVarsConfigurator) GetEthashDifficultyBoundDivisor() *big.Int { return vars.DifficultyBoundDivisor } -func (c GlobalVarsConfigurator) SetEthashDifficultyBoundDivisor(i *big.Int) error { +func (_ GlobalVarsConfigurator) SetEthashDifficultyBoundDivisor(i *big.Int) error { if i == nil { return ctypes.ErrUnsupportedConfigFatal } @@ -94,11 +96,11 @@ func (c GlobalVarsConfigurator) SetEthashDifficultyBoundDivisor(i *big.Int) erro return nil } -func (c GlobalVarsConfigurator) GetEthashDurationLimit() *big.Int { +func (_ GlobalVarsConfigurator) GetEthashDurationLimit() *big.Int { return vars.DurationLimit } -func (c GlobalVarsConfigurator) SetEthashDurationLimit(i *big.Int) error { +func (_ GlobalVarsConfigurator) SetEthashDurationLimit(i *big.Int) error { if i == nil { return ctypes.ErrUnsupportedConfigFatal } diff --git a/params/types/multigeth/chain_config_configurator.go b/params/types/multigeth/chain_config_configurator.go index c0e6e6c2da90..afa6002e1a9c 100644 --- a/params/types/multigeth/chain_config_configurator.go +++ b/params/types/multigeth/chain_config_configurator.go @@ -68,28 +68,28 @@ func (c *MultiGethChainConfig) ensureExistingDifficultySchedule() { } func (c *MultiGethChainConfig) GetAccountStartNonce() *uint64 { - return internal.One().GetAccountStartNonce() + return internal.GlobalConfigurator().GetAccountStartNonce() } func (c *MultiGethChainConfig) SetAccountStartNonce(n *uint64) error { - return internal.One().SetAccountStartNonce(n) + return internal.GlobalConfigurator().SetAccountStartNonce(n) } func (c *MultiGethChainConfig) GetMaximumExtraDataSize() *uint64 { - return internal.One().GetMaximumExtraDataSize() + return internal.GlobalConfigurator().GetMaximumExtraDataSize() } func (c *MultiGethChainConfig) SetMaximumExtraDataSize(n *uint64) error { - return internal.One().SetMaximumExtraDataSize(n) + return internal.GlobalConfigurator().SetMaximumExtraDataSize(n) } func (c *MultiGethChainConfig) GetMinGasLimit() *uint64 { - return internal.One().GetMinGasLimit() + return internal.GlobalConfigurator().GetMinGasLimit() } func (c *MultiGethChainConfig) SetMinGasLimit(n *uint64) error { - return internal.One().SetMinGasLimit(n) + return internal.GlobalConfigurator().SetMinGasLimit(n) } func (c *MultiGethChainConfig) GetGasLimitBoundDivisor() *uint64 { - return internal.One().GetGasLimitBoundDivisor() + return internal.GlobalConfigurator().GetGasLimitBoundDivisor() } func (c *MultiGethChainConfig) SetGasLimitBoundDivisor(n *uint64) error { - return internal.One().SetGasLimitBoundDivisor(n) + return internal.GlobalConfigurator().SetGasLimitBoundDivisor(n) } func (c *MultiGethChainConfig) GetNetworkID() *uint64 { @@ -114,10 +114,10 @@ func (c *MultiGethChainConfig) SetChainID(n *big.Int) error { } func (c *MultiGethChainConfig) GetMaxCodeSize() *uint64 { - return internal.One().GetMaxCodeSize() + return internal.GlobalConfigurator().GetMaxCodeSize() } func (c *MultiGethChainConfig) SetMaxCodeSize(n *uint64) error { - return internal.One().SetMaxCodeSize(n) + return internal.GlobalConfigurator().SetMaxCodeSize(n) } func (c *MultiGethChainConfig) GetEIP7Transition() *uint64 { @@ -401,26 +401,26 @@ func (c *MultiGethChainConfig) MustSetConsensusEngineType(t ctypes.ConsensusEngi } func (c *MultiGethChainConfig) GetEthashMinimumDifficulty() *big.Int { - return internal.One().GetEthashMinimumDifficulty() + return internal.GlobalConfigurator().GetEthashMinimumDifficulty() } func (c *MultiGethChainConfig) SetEthashMinimumDifficulty(i *big.Int) error { - return internal.One().SetEthashMinimumDifficulty(i) + return internal.GlobalConfigurator().SetEthashMinimumDifficulty(i) } func (c *MultiGethChainConfig) GetEthashDifficultyBoundDivisor() *big.Int { - return internal.One().GetEthashDifficultyBoundDivisor() + return internal.GlobalConfigurator().GetEthashDifficultyBoundDivisor() } func (c *MultiGethChainConfig) SetEthashDifficultyBoundDivisor(i *big.Int) error { - return internal.One().SetEthashDifficultyBoundDivisor(i) + return internal.GlobalConfigurator().SetEthashDifficultyBoundDivisor(i) } func (c *MultiGethChainConfig) GetEthashDurationLimit() *big.Int { - return internal.One().GetEthashDurationLimit() + return internal.GlobalConfigurator().GetEthashDurationLimit() } func (c *MultiGethChainConfig) SetEthashDurationLimit(i *big.Int) error { - return internal.One().SetEthashDurationLimit(i) + return internal.GlobalConfigurator().SetEthashDurationLimit(i) } func (c *MultiGethChainConfig) GetEthashHomesteadTransition() *uint64 { diff --git a/params/types/parity/parity.go b/params/types/parity/parity.go index fd6f3fe7f0c7..d5afd67e213e 100644 --- a/params/types/parity/parity.go +++ b/params/types/parity/parity.go @@ -21,6 +21,7 @@ import ( "encoding/json" "math/big" "reflect" + "sort" "strconv" "github.com/ethereum/go-ethereum/common" @@ -260,29 +261,39 @@ type ParityChainSpecPricingPrice struct { } func (p *ParityChainSpecPricingMaybe) UnmarshalJSON(input []byte) error { + + // If old schema structure with "pricing" field pricing := ParityChainSpecPricing{} err := json.Unmarshal(input, &pricing) if err == nil && !reflect.DeepEqual(pricing, ParityChainSpecPricing{}) { p.Pricing = &pricing return nil } - m := make(map[math.HexOrDecimal64]ParityChainSpecPricingPrice) - err = json.Unmarshal(input, &m) + + // Otherwise it's a map keyed on activation block numbers, + // where the keys are strings and could be duplicates. + // According to JSON specification we should use the last lexicographically + // ordered value in case of duplicates. + mm := make(map[string]ParityChainSpecPricingPrice) + err = json.Unmarshal(input, &mm) if err != nil { return err } - if len(m) == 0 { - panic("0 map, dragons") + sl := []string{} + for k := range mm { + sl = append(sl, k) } + sort.Strings(sl) p.Map = make(map[*math.HexOrDecimal256]ParityChainSpecPricingPrice) - for k, v := range m { - p.Map[math.NewHexOrDecimal256(int64(k))] = v + for _, s := range sl { + p.Map[(*math.HexOrDecimal256)(math.MustParseBig256(s))] = mm[s] } if len(p.Map) == 0 { panic("0map") } return nil } + func (p ParityChainSpecPricingMaybe) MarshalJSON() ([]byte, error) { if p.Map != nil { return json.Marshal(p.Map) diff --git a/params/types/parity/parity_test.go b/params/types/parity/parity_test.go index a7289009ab8f..f1a5b29f04d8 100644 --- a/params/types/parity/parity_test.go +++ b/params/types/parity/parity_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/davecgh/go-spew/spew" + "github.com/ethereum/go-ethereum/common" math2 "github.com/ethereum/go-ethereum/common/math" ) @@ -114,3 +115,137 @@ func TestParityChainSpec_UnmarshalJSON(t *testing.T) { t.Fatal(err) } } + +// TestParityChainSpec_GetPrecompile checks lexographical unmarshaling for maps which can +// have duplicate keys when unmarshaling builtin pricing. +func TestParityChainSpec_GetPrecompile(t *testing.T) { + pspec := &ParityChainSpec{} + err := json.Unmarshal([]byte(` +{ + "name": "Byzantium (Test)", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x29A2241AF62C0000", + "homesteadTransition": "0x0", + "eip100bTransition": "0x0", + "difficultyBombDelays": { + "0": 3000000 + } + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x1", + "maxCodeSize": 24576, + "maxCodeSizeTransition": "0x0", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip155Transition": "0x0", + "eip658Transition": "0x0" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } }, + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "pricing": { + "0": { + "price": { "alt_bn128_const_operations": { "price": 500 }} + }, + "0x7fffffffffffff": { + "info": "EIP 1108 transition", + "price": { "alt_bn128_const_operations": { "price": 150 }} + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "pricing": { + "42": { + "price": { "alt_bn128_const_operations": { "price": 50000 }} + }, + "42": { + "price": { "alt_bn128_const_operations": { "price": 40000 }} + }, + "0x2a": { + "price": { "alt_bn128_const_operations": { "price": 30000 }} + }, + "0x02a": { + "price": { "alt_bn128_const_operations": { "price": 10000 }} + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "pricing": { + "0": { + "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} + }, + "0x7fffffffffffff": { + "info": "EIP 1108 transition", + "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} + } + } + } + } + } +} +`), pspec) + if err != nil { + t.Fatal(err) + } + + // Use 'alt_bn128_mul' as our test case. + got := pspec.GetPrecompile(common.BytesToAddress([]byte{7}), + ParityChainSpecPricing{ + AltBnConstOperation: &ParityChainSpecAltBnConstOperationPricing{ + // Want 40000 because "42" lexically comes after "0x2a" and "0x02a". + // And then we cross our fingers and hope that literal order is preserved + // for the map during JSON unmarshaling with the keys as strings, since "42" == "42". + // We want bottom-wins parsing. + Price: 40000, + }, + }).Uint64P() + + want := uint64(42) + + if got == nil || *got != want { + t.Errorf("got: %v, want: %v", got, want) + } +}