Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evm: add whitelist deployer v2 #344

Merged
merged 10 commits into from
Sep 26, 2023
4 changes: 4 additions & 0 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,10 @@ func (s *StateDB) ValidDeployer(addr common.Address) bool {
return IsWhitelistedDeployer(s, addr)
}

func (s *StateDB) ValidDeployerV2(addr common.Address, blockTime uint64, whiteListContract *common.Address) bool {
return IsWhitelistedDeployerV2(s, addr, blockTime, whiteListContract)
}

func (s *StateDB) Blacklisted(contractAddr *common.Address, addr *common.Address) bool {
return IsAddressBlacklisted(s, contractAddr, addr)
}
Expand Down
38 changes: 38 additions & 0 deletions core/state/statedb_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var (
WHITELISTED: 1,
WHITELIST_ALL: 2,
}
slotWhitelistDeployerMappingV2 = map[string]uint64{
WHITELISTED: 53,
WHITELIST_ALL: 58,
} // Contract Infinity
slotBlacklistContractMapping = map[string]uint64{
BLACKLISTED: 1,
DISABLED: 2,
Expand All @@ -32,11 +36,45 @@ var (
}
)

// IsWhitelistedDeployer reads the contract storage to check if an address is allow to deploy
func IsWhitelistedDeployerV2(statedb *StateDB, address common.Address, blockTime uint64, whiteListContract *common.Address) bool {
contract := *whiteListContract
whitelistAllSlot := slotWhitelistDeployerMappingV2[WHITELIST_ALL]
whitelistAll := statedb.GetState(contract, GetLocSimpleVariable(whitelistAllSlot))

if whitelistAll.Big().Cmp(common.Big1) == 0 {
return true
}

whitelistedSlot := slotWhitelistDeployerMappingV2[WHITELISTED]
// WhiteListInfo have 2 fields, so we need to plus 1.
// struct WhiteListInfo {
// uint256 expiryTimestamp;
// bool activated;
// }
expiredLoc := GetLocMappingAtKey(address.Hash(), whitelistedSlot)
activatedLoc := common.BigToHash(expiredLoc.Big().Add(expiredLoc.Big(), common.Big1))
expiredHash := statedb.GetState(contract, expiredLoc)

activatedHash := statedb.GetState(contract, activatedLoc)

// (whiteListInfo.activated && block.timestamp < whiteListInfo.expiryTimestamp)
// Compare expiredHash with Blockheader timestamp.
if activatedHash.Big().Cmp(common.Big1) == 0 {
if expiredHash.Big().Cmp(big.NewInt(int64(blockTime))) > 0 {
// Block time still is in expiredTime
return true
}
}
return false
}

// IsWhitelistedDeployer reads the contract storage to check if an address is allow to deploy
func IsWhitelistedDeployer(statedb *StateDB, address common.Address) bool {
contract := common.HexToAddress(common.WhitelistDeployerSC)
whitelistAllSlot := slotWhitelistDeployerMapping[WHITELIST_ALL]
whitelistAll := statedb.GetState(contract, GetLocSimpleVariable(whitelistAllSlot))

if whitelistAll.Big().Cmp(big.NewInt(1)) == 0 {
return true
}
Expand Down
16 changes: 12 additions & 4 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,17 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}
}
}

if evm.chainRules.IsOdysseusFork && !evm.StateDB.ValidDeployer(caller.Address()) {
captureTraceEarly(ErrExecutionReverted)
return nil, common.Address{}, gas, ErrExecutionReverted
// Handle latest hardfork firstly.
if evm.chainRules.IsAntenna {
if !evm.StateDB.ValidDeployerV2(caller.Address(), evm.Context.Time, evm.ChainConfig().WhiteListDeployerContractV2Address) {
captureTraceEarly(ErrExecutionReverted)
return nil, common.Address{}, gas, ErrExecutionReverted
}
} else if evm.chainRules.IsOdysseusFork {
if !evm.StateDB.ValidDeployer(caller.Address()) {
captureTraceEarly(ErrExecutionReverted)
return nil, common.Address{}, gas, ErrExecutionReverted
}
}

// Depth check execution. Fail if we're trying to execute above the
Expand All @@ -517,6 +524,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
return nil, common.Address{}, gas, ErrInsufficientBalance
}
nonce := evm.StateDB.GetNonce(caller.Address())

if nonce+1 < nonce {
captureTraceEarly(ErrNonceUintOverflow)
return nil, common.Address{}, gas, ErrNonceUintOverflow
Expand Down
1 change: 1 addition & 0 deletions core/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type StateDB interface {
ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) error

ValidDeployer(common.Address) bool
ValidDeployerV2(common.Address, uint64, *common.Address) bool
Blacklisted(*common.Address, *common.Address) bool
}

Expand Down
187 changes: 187 additions & 0 deletions core/vm/statedb_utils_test.go

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion genesis/testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"puffyBlock": 12254000,
"bubaBlock": 14260600,
"olekBlock": 16849000,
"shillinBlock": 20268000
"shillinBlock": 20268000,
"antennaBlock": 20737258,
"whiteListDeployerContractV2Address": "0x50a7e07Aa75eB9C04281713224f50403cA79851F"
},
"alloc": {
"0x0000000000000000000000000000000000000011": {
Expand Down
57 changes: 38 additions & 19 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,21 +283,23 @@ var (
RoninTestnetStakingContractAddress = common.HexToAddress("0x9C245671791834daf3885533D24dce516B763B28")
RoninTestnetProfileContractAddress = common.HexToAddress("0x3b67c8D22a91572a6AB18acC9F70787Af04A4043")
RoninTestnetFinalityTrackingAddress = common.HexToAddress("0x41aCDFe786171824a037f2Cd6224c5916A58969a")
RoninWhiteListDeployerContractV2Address = common.HexToAddress("0x50a7e07Aa75eB9C04281713224f50403cA79851F")

RoninTestnetChainConfig = &ChainConfig{
ChainID: big.NewInt(2021),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
OdysseusBlock: big.NewInt(3315095),
FenixBlock: big.NewInt(6770400),
BlacklistContractAddress: &RoninTestnetBlacklistContract,
FenixValidatorContractAddress: &RoninTestnetFenixValidatorContractAddress,
ChainID: big.NewInt(2021),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
OdysseusBlock: big.NewInt(3315095),
FenixBlock: big.NewInt(6770400),
BlacklistContractAddress: &RoninTestnetBlacklistContract,
FenixValidatorContractAddress: &RoninTestnetFenixValidatorContractAddress,
WhiteListDeployerContractV2Address: &RoninWhiteListDeployerContractV2Address,
Consortium: &ConsortiumConfig{
Period: 3,
Epoch: 30,
Expand All @@ -315,6 +317,7 @@ var (
BubaBlock: big.NewInt(14260600),
OlekBlock: big.NewInt(16849000),
ShillinBlock: big.NewInt(20268000),
AntennaBlock: big.NewInt(20737258),
}

// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
Expand Down Expand Up @@ -528,9 +531,10 @@ type ChainConfig struct {
// Shillin hardfork introduces fast finality
ShillinBlock *big.Int `json:"shillinBlock,omitempty"` // Shillin switch block (nil = no fork, 0 = already on activated)

BlacklistContractAddress *common.Address `json:"blacklistContractAddress,omitempty"` // Address of Blacklist Contract (nil = no blacklist)
FenixValidatorContractAddress *common.Address `json:"fenixValidatorContractAddress,omitempty"` // Address of Ronin Contract in the Fenix hardfork (nil = no blacklist)

AntennaBlock *big.Int `json:"antennaBlock,omitempty"` // AntennaBlock switch block (nil = no fork, 0 = already on activated)
BlacklistContractAddress *common.Address `json:"blacklistContractAddress,omitempty"` // Address of Blacklist Contract (nil = no blacklist)
FenixValidatorContractAddress *common.Address `json:"fenixValidatorContractAddress,omitempty"` // Address of Ronin Contract in the Fenix hardfork (nil = no blacklist)
WhiteListDeployerContractV2Address *common.Address `json:"whiteListDeployerContractV2Address,omitempty"` // Address of Whitelist Ronin Contract V2 (nil = no blacklist)
// TerminalTotalDifficulty is the amount of total difficulty reached by
// the network that triggers the consensus upgrade.
TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"`
Expand Down Expand Up @@ -629,12 +633,16 @@ func (c *ChainConfig) String() string {
if c.ConsortiumV2Contracts != nil {
finalityTrackingContract = c.ConsortiumV2Contracts.FinalityTracking
}
whiteListDeployerContractV2Address := common.HexToAddress("")
if c.WhiteListDeployerContractV2Address != nil {
whiteListDeployerContractV2Address = *c.WhiteListDeployerContractV2Address
}

chainConfigFmt := "{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v "
chainConfigFmt += "Petersburg: %v Istanbul: %v, Odysseus: %v, Fenix: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, "
chainConfigFmt += "Engine: %v, Blacklist Contract: %v, Fenix Validator Contract: %v, ConsortiumV2: %v, ConsortiumV2.RoninValidatorSet: %v, "
chainConfigFmt += "ConsortiumV2.SlashIndicator: %v, ConsortiumV2.StakingContract: %v, Puffy: %v, Buba: %v, Olek: %v, Shillin: %v, "
chainConfigFmt += "ConsortiumV2.ProfileContract: %v, ConsortiumV2.FinalityTracking: %v}"
chainConfigFmt += "ConsortiumV2.SlashIndicator: %v, ConsortiumV2.StakingContract: %v, Puffy: %v, Buba: %v, Olek: %v, Shillin: %v, Antenna: %v, "
huyngopt1994 marked this conversation as resolved.
Show resolved Hide resolved
chainConfigFmt += "ConsortiumV2.ProfileContract: %v, ConsortiumV2.FinalityTracking: %v, whiteListDeployerContractV2Address: %v}"

return fmt.Sprintf(chainConfigFmt,
c.ChainID,
Expand Down Expand Up @@ -665,8 +673,10 @@ func (c *ChainConfig) String() string {
c.BubaBlock,
c.OlekBlock,
c.ShillinBlock,
c.AntennaBlock,
profileContract.Hex(),
finalityTrackingContract.Hex(),
whiteListDeployerContractV2Address.Hex(),
)
}

Expand Down Expand Up @@ -780,6 +790,11 @@ func (c *ChainConfig) IsOlek(num *big.Int) bool {
return isForked(c.OlekBlock, num)
}

// IsAntenna returns whether the num is equals to or larger than the Antenna fork block.
func (c *ChainConfig) IsAntenna(num *big.Int) bool {
return isForked(c.AntennaBlock, num)
}

// IsShillin returns whether the num is equals to or larger than the shillin fork block.
func (c *ChainConfig) IsShillin(num *big.Int) bool {
return isForked(c.ShillinBlock, num)
Expand Down Expand Up @@ -919,6 +934,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.ShillinBlock, newcfg.ShillinBlock, head) {
return newCompatError("Shillin fork block", c.ShillinBlock, newcfg.ShillinBlock)
}
if isForkIncompatible(c.AntennaBlock, newcfg.AntennaBlock, head) {
return newCompatError("Antenna fork block", c.AntennaBlock, newcfg.AntennaBlock)
}
return nil
}

Expand Down Expand Up @@ -987,7 +1005,7 @@ type Rules struct {
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
IsOdysseusFork, IsFenix, IsConsortiumV2 bool
IsOdysseusFork, IsFenix, IsConsortiumV2, IsAntenna bool
}

// Rules ensures c's ChainID is not nil.
Expand All @@ -1011,5 +1029,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
IsOdysseusFork: c.IsOdysseus(num),
IsFenix: c.IsFenix(num),
IsConsortiumV2: c.IsConsortiumV2(num),
IsAntenna: c.IsAntenna(num),
}
}