Support BSC Nano hardfork (#5654)

This commit is contained in:
Levi Aul 2022-10-06 23:20:48 -07:00 committed by GitHub
parent 6a55337266
commit 7144b2664c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 90 additions and 1 deletions

View File

@ -377,8 +377,20 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
homestead := st.evm.ChainRules().IsHomestead
istanbul := st.evm.ChainRules().IsIstanbul
london := st.evm.ChainRules().IsLondon
nano := st.evm.ChainRules().IsNano
contractCreation := msg.To() == nil
if nano {
for _, blackListAddr := range types.NanoBlackList {
if blackListAddr == sender.Address() {
return nil, fmt.Errorf("block blacklist account")
}
if msg.To() != nil && *msg.To() == blackListAddr {
return nil, fmt.Errorf("block blacklist account")
}
}
}
// Check clauses 4-5, subtract intrinsic gas if everything is correct
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, homestead, istanbul)
if err != nil {

11
core/types/blacklist.go Normal file
View File

@ -0,0 +1,11 @@
package types
import "github.com/ledgerwatch/erigon/common"
// This is introduced because of the Tendermint IAVL Merkel Proof verification exploitation.
var NanoBlackList = []common.Address{
common.HexToAddress("0x489A8756C18C0b8B24EC2a2b9FF3D4d447F79BEc"),
common.HexToAddress("0xFd6042Df3D74ce9959922FeC559d7995F3933c55"),
// Test Account
common.HexToAddress("0xdb789Eb5BDb4E559beD199B8b82dED94e1d056C9"),
}

View File

@ -95,6 +95,21 @@ var PrecompiledContractsIstanbulForBSC = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{101}): &iavlMerkleProofValidate{},
}
var PrecompiledContractsNano = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{100}): &tmHeaderValidateNano{},
common.BytesToAddress([]byte{101}): &iavlMerkleProofValidateNano{},
}
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
// contracts used in the Berlin release.
var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
@ -124,6 +139,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
}
var (
PrecompiledAddressesNano []common.Address
PrecompiledAddressesBerlin []common.Address
PrecompiledAddressesIstanbul []common.Address
PrecompiledAddressesIstanbulForBSC []common.Address
@ -147,11 +163,16 @@ func init() {
for k := range PrecompiledContractsBerlin {
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
}
for k := range PrecompiledContractsNano {
PrecompiledAddressesNano = append(PrecompiledAddressesNano, k)
}
}
// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules *params.Rules) []common.Address {
switch {
case rules.IsNano:
return PrecompiledAddressesNano
case rules.IsBerlin:
return PrecompiledAddressesBerlin
case rules.IsIstanbul:

View File

@ -133,3 +133,28 @@ func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01)
return result, nil
}
// tmHeaderValidate implemented as a native contract.
type tmHeaderValidateNano struct{}
func (c *tmHeaderValidateNano) RequiredGas(input []byte) uint64 {
return params.TendermintHeaderValidateGas
}
func (c *tmHeaderValidateNano) Run(input []byte) (result []byte, err error) {
return nil, fmt.Errorf("suspend")
}
// ------------------------------------------------------------------------------------------------------------------------------------------------
type iavlMerkleProofValidateNano struct{}
func (c *iavlMerkleProofValidateNano) RequiredGas(input []byte) uint64 {
return params.IAVLMerkleProofValidateGas
}
// input:
// | payload length | payload |
// | 32 bytes | |
func (c *iavlMerkleProofValidateNano) Run(input []byte) (result []byte, err error) {
return nil, fmt.Errorf("suspend")
}

View File

@ -45,6 +45,8 @@ type (
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract
switch {
case evm.chainRules.IsNano:
precompiles = PrecompiledContractsNano
case evm.chainRules.IsBerlin:
precompiles = PrecompiledContractsBerlin
case evm.chainRules.IsIstanbul:

View File

@ -16,6 +16,7 @@
"mirrorSyncBlock": 5184000,
"brunoBlock": 13082000,
"eulerBlock": 18907621,
"nanoBlock": 21962149,
"parlia": {
"DBPath": "",
"InMemory": false,

View File

@ -17,6 +17,7 @@
"brunoBlock": 13837000,
"eulerBlock": 19203503,
"gibbsBlock": 22800220,
"nanoBlock": 23482428,
"parlia": {
"DBPath": "",
"InMemory": false,

View File

@ -259,6 +259,7 @@ type ChainConfig struct {
BrunoBlock *big.Int `json:"brunoBlock,omitempty" toml:",omitempty"` // brunoBlock switch block (nil = no fork, 0 = already activated)
EulerBlock *big.Int `json:"eulerBlock,omitempty" toml:",omitempty"` // eulerBlock switch block (nil = no fork, 0 = already activated)
GibbsBlock *big.Int `json:"gibbsBlock,omitempty" toml:",omitempty"` // gibbsBlock switch block (nil = no fork, 0 = already activated)
NanoBlock *big.Int `json:"nanoBlock,omitempty" toml:",omitempty"` // nanoBlock switch block (nil = no fork, 0 = already activated)
// Gnosis Chain fork blocks
PosdaoBlock *big.Int `json:"posdaoBlock,omitempty"`
@ -398,7 +399,7 @@ func (c *ChainConfig) String() string {
// TODO Covalent: Refactor to more generic approach and potentially introduce tag for "ecosystem" field (Ethereum, BSC, etc.)
if c.Consensus == ParliaConsensus {
return fmt.Sprintf("{ChainID: %v Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Euler: %v, Gibbs: %v, Engine: %v}",
return fmt.Sprintf("{ChainID: %v Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Euler: %v, Gibbs: %v, Nano: %v, Engine: %v}",
c.ChainID,
c.RamanujanBlock,
c.NielsBlock,
@ -406,6 +407,7 @@ func (c *ChainConfig) String() string {
c.BrunoBlock,
c.EulerBlock,
c.GibbsBlock,
c.NanoBlock,
engine,
)
}
@ -550,6 +552,15 @@ func (c *ChainConfig) IsOnGibbs(num *big.Int) bool {
return configNumEqual(c.GibbsBlock, num)
}
// IsNano returns whether num is either equal to the euler fork block or greater.
func (c *ChainConfig) IsNano(num uint64) bool {
return isForked(c.NanoBlock, num)
}
func (c *ChainConfig) IsOnNano(num *big.Int) bool {
return configNumEqual(c.NanoBlock, num)
}
// IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
func (c *ChainConfig) IsMuirGlacier(num uint64) bool {
return isForked(c.MuirGlacierBlock, num)
@ -748,6 +759,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head uint64) *ConfigC
if isForkIncompatible(c.GibbsBlock, newcfg.GibbsBlock, head) {
return newCompatError("Gibbs fork block", c.GibbsBlock, newcfg.GibbsBlock)
}
if isForkIncompatible(c.NanoBlock, newcfg.NanoBlock, head) {
return newCompatError("Nano fork block", c.NanoBlock, newcfg.NanoBlock)
}
return nil
}
@ -817,6 +831,7 @@ type Rules struct {
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon, IsShanghai, IsCancun bool
IsParlia, IsStarknet, IsAura bool
IsNano bool
}
// Rules ensures c's ChainID is not nil.
@ -838,6 +853,7 @@ func (c *ChainConfig) Rules(num uint64) *Rules {
IsLondon: c.IsLondon(num),
IsShanghai: c.IsShanghai(num),
IsCancun: c.IsCancun(num),
IsNano: c.IsNano(num),
IsParlia: c.Parlia != nil,
IsAura: c.Aura != nil,
}