mirror of https://github.com/poanetwork/quorum.git
parent c215989c10
author vsmk98 <vsaimk@gmail.com> 1585565614 +0800 committer Trung Nguyen <24930+trung@users.noreply.github.com> 1588174146 -0400 gpgsig -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEzAFy365WU5uP2ESgRjZDTtlQXrcFAl6pnUIACgkQRjZDTtlQ XrcL2Af+IKHLFkPhSoEHvhN+KDEKqNt1GFZQuLLUhgP9yFsbnbgPlUaYPSkWTAOk v0EMUnYUjNsKSj6PsWj4CaW2DBovInIGE/R1oWjmpjPY+IiLJZHg9S+3o9D/pRd6 a/jXcTdsL9t/u9RqZICzJwVEWcSFNHWH8/EhWpf/NExrxgiue9Ib146hzJn7Rzss vgts6vco87r+ck6SZlqNrldwz/V1kKQXDRsTrPC4h7sJ6DTG+NgGDjXu9A5PuVB2 9byGG1EDNTuqhaHJoUu32m3qs61WKXprTAuo3Bo4i38yemiotPKotBCNKo1odbrV h9mseIdlSfWEOx0SdfbVXe3qMMYe7w== =7LJs -----END PGP SIGNATURE----- Enable networks to change maxCodeSize multiple times #975 Current maxCodeSize implementation allows change of maxCodeSize once in network life. If the maxCodeSize is changed multiple times, its possible that any new node joining the network can get Bad block error while syncing the blocks as the historical value of maxCodeSize at that particular block height may not match with the current maxCodeSize. It should be possible to track the historical changes of maxCodeSize in genesis and thus allow it to be changed multiple times in network life.
This commit is contained in:
parent
c215989c10
commit
5cab3a794d
|
@ -231,6 +231,13 @@ func initGenesis(ctx *cli.Context) error {
|
|||
file.Seek(0, 0)
|
||||
genesis.Config.IsQuorum = getIsQuorum(file)
|
||||
|
||||
// check the data given as a part of newMaxConfigData to ensure that
|
||||
// its in expected order
|
||||
err = genesis.Config.CheckMaxCodeConfigData()
|
||||
if err != nil {
|
||||
utils.Fatalf("maxCodeSize data invalid: %v", err)
|
||||
}
|
||||
|
||||
// Open an initialise both full and light databases
|
||||
stack := makeFullNode(ctx)
|
||||
defer stack.Close()
|
||||
|
|
|
@ -173,10 +173,6 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
|
|||
if genesis.Config.TransactionSizeLimit == 0 {
|
||||
genesis.Config.TransactionSizeLimit = DefaultTxPoolConfig.TransactionSizeLimit
|
||||
}
|
||||
// Set default contract size limit that can be deployed if not set in genesis
|
||||
if genesis.Config.MaxCodeSize == 0 {
|
||||
genesis.Config.MaxCodeSize = DefaultTxPoolConfig.MaxCodeSize
|
||||
}
|
||||
|
||||
// Check transaction size limit and max contract code size
|
||||
err := genesis.Config.IsValid()
|
||||
|
|
|
@ -500,14 +500,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
|
||||
ret, err := run(evm, contract, nil, false)
|
||||
|
||||
// Quorum
|
||||
maxCodeSize := evm.ChainConfig().GetMaxCodeSize(evm.BlockNumber)
|
||||
// check whether the max code size has been exceeded, check maxcode size from chain config
|
||||
var maxCodeSize int
|
||||
if evm.chainConfig.IsMaxCodeSizeChangeBlock(evm.BlockNumber) && evm.ChainConfig().MaxCodeSize > 0 {
|
||||
maxCodeSize = int(evm.ChainConfig().MaxCodeSize * 1024)
|
||||
} else {
|
||||
maxCodeSize = params.MaxCodeSize
|
||||
}
|
||||
maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > maxCodeSize
|
||||
// if the contract creation ran successfully and no errors were returned
|
||||
// calculate the gas required to store the code. If the code could not
|
||||
|
|
|
@ -897,11 +897,19 @@ type NodeInfo struct {
|
|||
// NodeInfo retrieves some protocol metadata about the running host node.
|
||||
func (pm *ProtocolManager) NodeInfo() *NodeInfo {
|
||||
currentBlock := pm.blockchain.CurrentBlock()
|
||||
// //Quorum
|
||||
//
|
||||
// changes done to fetch maxCodeSize dynamically based on the
|
||||
// maxCodeSizeConfig changes
|
||||
// /Quorum
|
||||
chainConfig := pm.blockchain.Config()
|
||||
chainConfig.MaxCodeSize = uint64(chainConfig.GetMaxCodeSize(pm.blockchain.CurrentBlock().Number()) / 1024)
|
||||
|
||||
return &NodeInfo{
|
||||
Network: pm.networkID,
|
||||
Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
|
||||
Genesis: pm.blockchain.Genesis().Hash(),
|
||||
Config: pm.blockchain.Config(),
|
||||
Config: chainConfig,
|
||||
Head: currentBlock.Hash(),
|
||||
Consensus: pm.getConsensusAlgorithm(),
|
||||
}
|
||||
|
|
142
params/config.go
142
params/config.go
|
@ -214,19 +214,19 @@ var (
|
|||
//
|
||||
// This configuration is intentionally not using keyed fields to force anyone
|
||||
// adding flags to the config to also have to set these fields.
|
||||
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0)}
|
||||
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil}
|
||||
|
||||
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||
// and accepted by the Ethereum core developers into the Clique consensus.
|
||||
//
|
||||
// This configuration is intentionally not using keyed fields to force anyone
|
||||
// adding flags to the config to also have to set these fields.
|
||||
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, false, 32, 32, big.NewInt(0), big.NewInt(0)}
|
||||
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil}
|
||||
|
||||
TestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0)}
|
||||
TestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil}
|
||||
TestRules = TestChainConfig.Rules(new(big.Int))
|
||||
|
||||
QuorumTestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, true, 64, 32, big.NewInt(0), big.NewInt(0)}
|
||||
QuorumTestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, true, 64, 32, big.NewInt(0), big.NewInt(0), nil}
|
||||
)
|
||||
|
||||
// TrustedCheckpoint represents a set of post-processed trie roots (CHT and
|
||||
|
@ -271,6 +271,11 @@ type CheckpointOracleConfig struct {
|
|||
Threshold uint64 `json:"threshold"`
|
||||
}
|
||||
|
||||
type MaxCodeConfigStruct struct {
|
||||
Block *big.Int `json:"block,omitempty"`
|
||||
Size uint64 `json:"size,omitempty"`
|
||||
}
|
||||
|
||||
// ChainConfig is the core config which determines the blockchain settings.
|
||||
//
|
||||
// ChainConfig is stored in the database on a per block basis. This means
|
||||
|
@ -310,6 +315,9 @@ type ChainConfig struct {
|
|||
// QIP714Block implements the permissions related changes
|
||||
QIP714Block *big.Int `json:"qip714Block,omitempty"`
|
||||
MaxCodeSizeChangeBlock *big.Int `json:"maxCodeSizeChangeBlock,omitempty"`
|
||||
// to track multiple changes to maxCodeSize
|
||||
MaxCodeSizeConfig []MaxCodeConfigStruct `json:"maxCodeSizeConfig,omitempty"`
|
||||
// Quorum
|
||||
}
|
||||
|
||||
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
||||
|
@ -384,7 +392,7 @@ func (c *ChainConfig) IsValid() error {
|
|||
return errors.New("Genesis transaction size limit must be between 32 and 128")
|
||||
}
|
||||
|
||||
if c.MaxCodeSize < 24 || c.MaxCodeSize > 128 {
|
||||
if c.MaxCodeSize != 0 && (c.MaxCodeSize < 24 || c.MaxCodeSize > 128) {
|
||||
return errors.New("Genesis max code size must be between 24 and 128")
|
||||
}
|
||||
|
||||
|
@ -450,19 +458,133 @@ func (c *ChainConfig) IsQIP714(num *big.Int) bool {
|
|||
return isForked(c.QIP714Block, num)
|
||||
}
|
||||
|
||||
// Quorum
|
||||
//
|
||||
// IsMaxCodeSizeChangeBlock returns whether num represents a block number max code size
|
||||
// was changed from default 24K to new value
|
||||
// IsMaxCodeSizeChangeBlock returns whether num represents a block number
|
||||
// where maxCodeSize change was done
|
||||
func (c *ChainConfig) IsMaxCodeSizeChangeBlock(num *big.Int) bool {
|
||||
return isForked(c.MaxCodeSizeChangeBlock, num)
|
||||
}
|
||||
|
||||
// Quorum
|
||||
//
|
||||
// GetMaxCodeSize returns maxCodeSize for the given block number
|
||||
func (c *ChainConfig) GetMaxCodeSize(num *big.Int) int {
|
||||
maxCodeSize := MaxCodeSize
|
||||
|
||||
if len(c.MaxCodeSizeConfig) > 0 {
|
||||
for _, data := range c.MaxCodeSizeConfig {
|
||||
if data.Block.Cmp(num) > 0 {
|
||||
break
|
||||
}
|
||||
maxCodeSize = int(data.Size) * 1024
|
||||
}
|
||||
} else if c.MaxCodeSize > 0 {
|
||||
if c.MaxCodeSizeChangeBlock != nil && c.MaxCodeSizeChangeBlock.Cmp(big.NewInt(0)) >= 0 {
|
||||
if c.IsMaxCodeSizeChangeBlock(num) {
|
||||
maxCodeSize = int(c.MaxCodeSize) * 1024
|
||||
}
|
||||
} else {
|
||||
maxCodeSize = int(c.MaxCodeSize) * 1024
|
||||
}
|
||||
}
|
||||
return maxCodeSize
|
||||
}
|
||||
|
||||
// validates the maxCodeSizeConfig data passed in config
|
||||
func (c *ChainConfig) CheckMaxCodeConfigData() error {
|
||||
if c.MaxCodeSize != 0 || (c.MaxCodeSizeChangeBlock != nil && c.MaxCodeSizeChangeBlock.Cmp(big.NewInt(0)) >= 0) {
|
||||
return errors.New("maxCodeSize & maxCodeSizeChangeBlock deprecated. Consider using maxCodeSizeConfig")
|
||||
}
|
||||
// validate max code size data
|
||||
// 1. Code size should not be less than 24 and greater than 128
|
||||
// 2. block entries are in ascending order
|
||||
prevBlock := big.NewInt(0)
|
||||
for _, data := range c.MaxCodeSizeConfig {
|
||||
if data.Size < 24 || data.Size > 128 {
|
||||
return errors.New("Genesis max code size must be between 24 and 128")
|
||||
}
|
||||
if data.Block == nil {
|
||||
return errors.New("Block number not given in maxCodeSizeConfig data")
|
||||
}
|
||||
if data.Block.Cmp(prevBlock) < 0 {
|
||||
return errors.New("invalid maxCodeSize detail, block order has to be ascending")
|
||||
}
|
||||
prevBlock = data.Block
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checks if changes to maxCodeSizeConfig proposed are compatible
|
||||
// with already existing genesis data
|
||||
func isMaxCodeSizeConfigCompatible(c1, c2 *ChainConfig, head *big.Int) (error, *big.Int, *big.Int) {
|
||||
if len(c1.MaxCodeSizeConfig) == 0 && len(c2.MaxCodeSizeConfig) == 0 {
|
||||
// maxCodeSizeConfig not used. return
|
||||
return nil, big.NewInt(0), big.NewInt(0)
|
||||
}
|
||||
|
||||
// existing config had maxCodeSizeConfig and new one does not have the same return error
|
||||
if len(c1.MaxCodeSizeConfig) > 0 && len(c2.MaxCodeSizeConfig) == 0 {
|
||||
return fmt.Errorf("genesis file missing max code size information"), head, head
|
||||
}
|
||||
|
||||
if len(c2.MaxCodeSizeConfig) > 0 && len(c1.MaxCodeSizeConfig) == 0 {
|
||||
return nil, big.NewInt(0), big.NewInt(0)
|
||||
}
|
||||
|
||||
// check the number of records below current head in both configs
|
||||
// if they do not match throw an error
|
||||
c1RecsBelowHead := 0
|
||||
for _, data := range c1.MaxCodeSizeConfig {
|
||||
if data.Block.Cmp(head) <= 0 {
|
||||
c1RecsBelowHead++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
c2RecsBelowHead := 0
|
||||
for _, data := range c2.MaxCodeSizeConfig {
|
||||
if data.Block.Cmp(head) <= 0 {
|
||||
c2RecsBelowHead++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// if the count of past records is not matching return error
|
||||
if c1RecsBelowHead != c2RecsBelowHead {
|
||||
return errors.New("maxCodeSizeConfig data incompatible. updating maxCodeSize for past"), head, head
|
||||
}
|
||||
|
||||
// validate that each past record is matching exactly. if not return error
|
||||
for i := 0; i < c1RecsBelowHead; i++ {
|
||||
if c1.MaxCodeSizeConfig[i].Block.Cmp(c2.MaxCodeSizeConfig[i].Block) != 0 ||
|
||||
c1.MaxCodeSizeConfig[i].Size != c2.MaxCodeSizeConfig[i].Size {
|
||||
return errors.New("maxCodeSizeConfig data incompatible. maxCodeSize historical data does not match"), head, head
|
||||
}
|
||||
}
|
||||
|
||||
return nil, big.NewInt(0), big.NewInt(0)
|
||||
}
|
||||
|
||||
// /Quorum
|
||||
|
||||
// CheckCompatible checks whether scheduled fork transitions have been imported
|
||||
// with a mismatching chain configuration.
|
||||
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, isQuorumEIP155Activated bool) *ConfigCompatError {
|
||||
bhead := new(big.Int).SetUint64(height)
|
||||
|
||||
// check if the maxCodesize data passed is compatible 1st
|
||||
// this is being handled separately as it can have breaks
|
||||
// at multiple block heights and cannot be handled with in
|
||||
// checkCompatible
|
||||
|
||||
// compare the maxCodeSize data between the old and new config
|
||||
err, cBlock, newCfgBlock := isMaxCodeSizeConfigCompatible(c, newcfg, bhead)
|
||||
if err != nil {
|
||||
return newCompatError(err.Error(), cBlock, newCfgBlock)
|
||||
}
|
||||
|
||||
// Iterate checkCompatible to find the lowest conflict.
|
||||
var lasterr *ConfigCompatError
|
||||
for {
|
||||
|
@ -558,7 +680,7 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int, isQuor
|
|||
if isForkIncompatible(c.QIP714Block, newcfg.QIP714Block, head) {
|
||||
return newCompatError("permissions fork block", c.QIP714Block, newcfg.QIP714Block)
|
||||
}
|
||||
if isForkIncompatible(c.MaxCodeSizeChangeBlock, newcfg.MaxCodeSizeChangeBlock, head) {
|
||||
if newcfg.MaxCodeSizeChangeBlock != nil && isForkIncompatible(c.MaxCodeSizeChangeBlock, newcfg.MaxCodeSizeChangeBlock, head) {
|
||||
return newCompatError("max code size change fork block", c.MaxCodeSizeChangeBlock, newcfg.MaxCodeSizeChangeBlock)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -92,6 +92,31 @@ func TestCheckCompatible(t *testing.T) {
|
|||
head uint64
|
||||
wantErr *ConfigCompatError
|
||||
}
|
||||
var storedMaxCodeConfig0, storedMaxCodeConfig1, storedMaxCodeConfig2 []MaxCodeConfigStruct
|
||||
defaultRec := MaxCodeConfigStruct{big.NewInt(0), 24}
|
||||
rec1 := MaxCodeConfigStruct{big.NewInt(5), 32}
|
||||
rec2 := MaxCodeConfigStruct{big.NewInt(10), 40}
|
||||
rec3 := MaxCodeConfigStruct{big.NewInt(8), 40}
|
||||
|
||||
|
||||
storedMaxCodeConfig0 = append(storedMaxCodeConfig0, defaultRec)
|
||||
|
||||
storedMaxCodeConfig1 = append(storedMaxCodeConfig1, defaultRec)
|
||||
storedMaxCodeConfig1 = append(storedMaxCodeConfig1, rec1)
|
||||
storedMaxCodeConfig1 = append(storedMaxCodeConfig1, rec2)
|
||||
|
||||
storedMaxCodeConfig2 = append(storedMaxCodeConfig2, rec1)
|
||||
storedMaxCodeConfig2 = append(storedMaxCodeConfig2, rec2)
|
||||
|
||||
var passedValidMaxConfig0 []MaxCodeConfigStruct
|
||||
passedValidMaxConfig0 = append(passedValidMaxConfig0, defaultRec)
|
||||
passedValidMaxConfig0 = append(passedValidMaxConfig0, rec1)
|
||||
|
||||
var passedValidMaxConfig1 []MaxCodeConfigStruct
|
||||
passedValidMaxConfig1 = append(passedValidMaxConfig1, defaultRec)
|
||||
passedValidMaxConfig1 = append(passedValidMaxConfig1, rec1)
|
||||
passedValidMaxConfig1 = append(passedValidMaxConfig1, rec3)
|
||||
|
||||
tests := []test{
|
||||
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 0, wantErr: nil},
|
||||
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 100, wantErr: nil},
|
||||
|
@ -152,8 +177,8 @@ func TestCheckCompatible(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeChangeBlock:big.NewInt(10)},
|
||||
new: &ChainConfig{MaxCodeSizeChangeBlock:big.NewInt(20)},
|
||||
stored: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(10)},
|
||||
new: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(20)},
|
||||
head: 30,
|
||||
wantErr: &ConfigCompatError{
|
||||
What: "max code size change fork block",
|
||||
|
@ -163,14 +188,14 @@ func TestCheckCompatible(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeChangeBlock:big.NewInt(10)},
|
||||
new: &ChainConfig{MaxCodeSizeChangeBlock:big.NewInt(20)},
|
||||
stored: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(10)},
|
||||
new: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(20)},
|
||||
head: 4,
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{QIP714Block:big.NewInt(10)},
|
||||
new: &ChainConfig{QIP714Block:big.NewInt(20)},
|
||||
stored: &ChainConfig{QIP714Block: big.NewInt(10)},
|
||||
new: &ChainConfig{QIP714Block: big.NewInt(20)},
|
||||
head: 30,
|
||||
wantErr: &ConfigCompatError{
|
||||
What: "permissions fork block",
|
||||
|
@ -180,12 +205,80 @@ func TestCheckCompatible(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{QIP714Block:big.NewInt(10)},
|
||||
new: &ChainConfig{QIP714Block:big.NewInt(20)},
|
||||
stored: &ChainConfig{QIP714Block: big.NewInt(10)},
|
||||
new: &ChainConfig{QIP714Block: big.NewInt(20)},
|
||||
head: 4,
|
||||
wantErr: nil,
|
||||
},
|
||||
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig0},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: nil},
|
||||
head: 4,
|
||||
wantErr: &ConfigCompatError{
|
||||
What: "genesis file missing max code size information",
|
||||
StoredConfig: big.NewInt(4),
|
||||
NewConfig: big.NewInt(4),
|
||||
RewindTo: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig0},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig0},
|
||||
head: 4,
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig0},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: passedValidMaxConfig0},
|
||||
head: 10,
|
||||
wantErr: &ConfigCompatError{
|
||||
What: "maxCodeSizeConfig data incompatible. updating maxCodeSize for past",
|
||||
StoredConfig: big.NewInt(10),
|
||||
NewConfig: big.NewInt(10),
|
||||
RewindTo: 9,
|
||||
},
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig0},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: passedValidMaxConfig0},
|
||||
head: 4,
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig1},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig1},
|
||||
head: 12,
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig1},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: passedValidMaxConfig1},
|
||||
head: 12,
|
||||
wantErr: &ConfigCompatError{
|
||||
What: "maxCodeSizeConfig data incompatible. maxCodeSize historical data does not match",
|
||||
StoredConfig: big.NewInt(12),
|
||||
NewConfig: big.NewInt(12),
|
||||
RewindTo: 11,
|
||||
},
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSize: 32},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig2},
|
||||
head: 8,
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSize: 32},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig2},
|
||||
head: 15,
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
stored: &ChainConfig{MaxCodeSize: 32, MaxCodeSizeChangeBlock:big.NewInt(10)},
|
||||
new: &ChainConfig{MaxCodeSizeConfig: storedMaxCodeConfig1},
|
||||
head: 15,
|
||||
wantErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
Loading…
Reference in New Issue