Skip to content

Commit

Permalink
evm: add whitelist deployer v2 (#344)
Browse files Browse the repository at this point in the history
* evm: add whitelist deployer v2

* statedb-utils: Add unit testing

* Update Antennablock for testnet

* Add params and update block in genesis

* Update check compatibility and params config
  • Loading branch information
huyngopt1994 authored Sep 26, 2023
1 parent 83c8375 commit 923653f
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 24 deletions.
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, "
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),
}
}

0 comments on commit 923653f

Please sign in to comment.