mirror of https://github.com/poanetwork/quorum.git
Enable networks to change maxCodeSize multiple times (#975)
This commit is contained in:
parent
4c6727c959
commit
b4e2199ca1
|
@ -231,6 +231,13 @@ func initGenesis(ctx *cli.Context) error {
|
||||||
file.Seek(0, 0)
|
file.Seek(0, 0)
|
||||||
genesis.Config.IsQuorum = getIsQuorum(file)
|
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
|
// Open an initialise both full and light databases
|
||||||
stack := makeFullNode(ctx)
|
stack := makeFullNode(ctx)
|
||||||
defer stack.Close()
|
defer stack.Close()
|
||||||
|
|
|
@ -173,10 +173,6 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
|
||||||
if genesis.Config.TransactionSizeLimit == 0 {
|
if genesis.Config.TransactionSizeLimit == 0 {
|
||||||
genesis.Config.TransactionSizeLimit = DefaultTxPoolConfig.TransactionSizeLimit
|
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
|
// Check transaction size limit and max contract code size
|
||||||
err := genesis.Config.IsValid()
|
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)
|
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
|
// 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
|
maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > maxCodeSize
|
||||||
// if the contract creation ran successfully and no errors were returned
|
// if the contract creation ran successfully and no errors were returned
|
||||||
// calculate the gas required to store the code. If the code could not
|
// 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.
|
// NodeInfo retrieves some protocol metadata about the running host node.
|
||||||
func (pm *ProtocolManager) NodeInfo() *NodeInfo {
|
func (pm *ProtocolManager) NodeInfo() *NodeInfo {
|
||||||
currentBlock := pm.blockchain.CurrentBlock()
|
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{
|
return &NodeInfo{
|
||||||
Network: pm.networkID,
|
Network: pm.networkID,
|
||||||
Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
|
Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
|
||||||
Genesis: pm.blockchain.Genesis().Hash(),
|
Genesis: pm.blockchain.Genesis().Hash(),
|
||||||
Config: pm.blockchain.Config(),
|
Config: chainConfig,
|
||||||
Head: currentBlock.Hash(),
|
Head: currentBlock.Hash(),
|
||||||
Consensus: pm.getConsensusAlgorithm(),
|
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
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// 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
|
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
// and accepted by the Ethereum core developers into the Clique consensus.
|
// and accepted by the Ethereum core developers into the Clique consensus.
|
||||||
//
|
//
|
||||||
// This configuration is intentionally not using keyed fields to force anyone
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// 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))
|
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
|
// TrustedCheckpoint represents a set of post-processed trie roots (CHT and
|
||||||
|
@ -271,6 +271,11 @@ type CheckpointOracleConfig struct {
|
||||||
Threshold uint64 `json:"threshold"`
|
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 the core config which determines the blockchain settings.
|
||||||
//
|
//
|
||||||
// ChainConfig is stored in the database on a per block basis. This means
|
// 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 implements the permissions related changes
|
||||||
QIP714Block *big.Int `json:"qip714Block,omitempty"`
|
QIP714Block *big.Int `json:"qip714Block,omitempty"`
|
||||||
MaxCodeSizeChangeBlock *big.Int `json:"maxCodeSizeChangeBlock,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.
|
// 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")
|
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")
|
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)
|
return isForked(c.QIP714Block, num)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quorum
|
// IsMaxCodeSizeChangeBlock returns whether num represents a block number
|
||||||
//
|
// where maxCodeSize change was done
|
||||||
// IsMaxCodeSizeChangeBlock returns whether num represents a block number max code size
|
|
||||||
// was changed from default 24K to new value
|
|
||||||
func (c *ChainConfig) IsMaxCodeSizeChangeBlock(num *big.Int) bool {
|
func (c *ChainConfig) IsMaxCodeSizeChangeBlock(num *big.Int) bool {
|
||||||
return isForked(c.MaxCodeSizeChangeBlock, num)
|
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
|
// CheckCompatible checks whether scheduled fork transitions have been imported
|
||||||
// with a mismatching chain configuration.
|
// with a mismatching chain configuration.
|
||||||
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, isQuorumEIP155Activated bool) *ConfigCompatError {
|
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, isQuorumEIP155Activated bool) *ConfigCompatError {
|
||||||
bhead := new(big.Int).SetUint64(height)
|
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.
|
// Iterate checkCompatible to find the lowest conflict.
|
||||||
var lasterr *ConfigCompatError
|
var lasterr *ConfigCompatError
|
||||||
for {
|
for {
|
||||||
|
@ -558,7 +680,7 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int, isQuor
|
||||||
if isForkIncompatible(c.QIP714Block, newcfg.QIP714Block, head) {
|
if isForkIncompatible(c.QIP714Block, newcfg.QIP714Block, head) {
|
||||||
return newCompatError("permissions fork block", c.QIP714Block, newcfg.QIP714Block)
|
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 newCompatError("max code size change fork block", c.MaxCodeSizeChangeBlock, newcfg.MaxCodeSizeChangeBlock)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -92,6 +92,31 @@ func TestCheckCompatible(t *testing.T) {
|
||||||
head uint64
|
head uint64
|
||||||
wantErr *ConfigCompatError
|
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{
|
tests := []test{
|
||||||
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 0, wantErr: nil},
|
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 0, wantErr: nil},
|
||||||
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 100, 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)},
|
stored: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(10)},
|
||||||
new: &ChainConfig{MaxCodeSizeChangeBlock:big.NewInt(20)},
|
new: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(20)},
|
||||||
head: 30,
|
head: 30,
|
||||||
wantErr: &ConfigCompatError{
|
wantErr: &ConfigCompatError{
|
||||||
What: "max code size change fork block",
|
What: "max code size change fork block",
|
||||||
|
@ -163,14 +188,14 @@ func TestCheckCompatible(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
stored: &ChainConfig{MaxCodeSizeChangeBlock:big.NewInt(10)},
|
stored: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(10)},
|
||||||
new: &ChainConfig{MaxCodeSizeChangeBlock:big.NewInt(20)},
|
new: &ChainConfig{MaxCodeSizeChangeBlock: big.NewInt(20)},
|
||||||
head: 4,
|
head: 4,
|
||||||
wantErr: nil,
|
wantErr: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
stored: &ChainConfig{QIP714Block:big.NewInt(10)},
|
stored: &ChainConfig{QIP714Block: big.NewInt(10)},
|
||||||
new: &ChainConfig{QIP714Block:big.NewInt(20)},
|
new: &ChainConfig{QIP714Block: big.NewInt(20)},
|
||||||
head: 30,
|
head: 30,
|
||||||
wantErr: &ConfigCompatError{
|
wantErr: &ConfigCompatError{
|
||||||
What: "permissions fork block",
|
What: "permissions fork block",
|
||||||
|
@ -180,12 +205,80 @@ func TestCheckCompatible(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
stored: &ChainConfig{QIP714Block:big.NewInt(10)},
|
stored: &ChainConfig{QIP714Block: big.NewInt(10)},
|
||||||
new: &ChainConfig{QIP714Block:big.NewInt(20)},
|
new: &ChainConfig{QIP714Block: big.NewInt(20)},
|
||||||
head: 4,
|
head: 4,
|
||||||
wantErr: nil,
|
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 {
|
for _, test := range tests {
|
||||||
|
|
Loading…
Reference in New Issue