Skip to content

Commit

Permalink
nanofork: add black list account (bnb-chain#1109)
Browse files Browse the repository at this point in the history
  • Loading branch information
unclezoro committed Oct 7, 2022
1 parent 3354924 commit 5b35b39
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Expand Up @@ -27,7 +27,7 @@ ENV HOME=${BSC_HOME}
ENV DATA_DIR=/data

ENV PACKAGES ca-certificates~=20220614 jq~=1.6 \
bash~=5.1.16-r2 bind-tools~=9.16.29-r0 tini~=0.19.0 \
bash~=5.1.16-r2 bind-tools tini~=0.19.0 \
grep~=3.7 curl~=7.83.1-r2 sed~=4.8-r0 curl~=7.83

RUN apk add --no-cache $PACKAGES \
Expand Down
10 changes: 10 additions & 0 deletions core/state_transition.go
Expand Up @@ -290,6 +290,16 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
}
msg := st.msg
sender := vm.AccountRef(msg.From())
if st.evm.ChainConfig().IsNano(st.evm.Context.BlockNumber) {
for _, blackListAddr := range types.NanoBlackList {
if blackListAddr == msg.From() {
return nil, fmt.Errorf("block blacklist account")
}
if msg.To() != nil && *msg.To() == blackListAddr {
return nil, fmt.Errorf("block blacklist account")
}
}
}
homestead := st.evm.ChainConfig().IsHomestead(st.evm.Context.BlockNumber)
istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.Context.BlockNumber)
london := st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber)
Expand Down
14 changes: 12 additions & 2 deletions core/tx_pool.go
Expand Up @@ -948,14 +948,24 @@ func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error {
// Exclude transactions with invalid signatures as soon as
// possible and cache senders in transactions before
// obtaining lock
_, err := types.Sender(pool.signer, tx)
sender, err := types.Sender(pool.signer, tx)
if err != nil {
errs[i] = ErrInvalidSender
invalidTxMeter.Mark(1)
continue
}
shouldBlock := false
for _, blackAddr := range types.NanoBlackList {
if sender == blackAddr || (tx.To() != nil && *tx.To() == blackAddr) {
shouldBlock = true
log.Error("blacklist account detected", "account", blackAddr, "tx", tx.Hash())
break
}
}
// Accumulate all unknown transactions for deeper processing
news = append(news, tx)
if !shouldBlock {
news = append(news, tx)
}
}
if len(news) == 0 {
return errs
Expand Down
11 changes: 11 additions & 0 deletions core/types/blacklist.go
@@ -0,0 +1,11 @@
package types

import "github.com/ethereum/go-ethereum/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"),
}
21 changes: 21 additions & 0 deletions core/vm/contracts.go
Expand Up @@ -81,6 +81,21 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{101}): &iavlMerkleProofValidate{},
}

var PrecompiledContractsIsNano = 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{
Expand Down Expand Up @@ -110,6 +125,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
}

var (
PrecompiledAddressesNano []common.Address
PrecompiledAddressesBerlin []common.Address
PrecompiledAddressesIstanbul []common.Address
PrecompiledAddressesByzantium []common.Address
Expand All @@ -129,11 +145,16 @@ func init() {
for k := range PrecompiledContractsBerlin {
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
}
for k := range PrecompiledContractsIsNano {
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:
Expand Down
26 changes: 26 additions & 0 deletions core/vm/contracts_lightclient.go
Expand Up @@ -104,6 +104,7 @@ func (c *iavlMerkleProofValidate) RequiredGas(input []byte) uint64 {
// | payload length | payload |
// | 32 bytes | |
func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
//return nil, fmt.Errorf("suspend")
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("internal error: %v\n", r)
Expand Down Expand Up @@ -133,3 +134,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")
}
2 changes: 2 additions & 0 deletions core/vm/evm.go
Expand Up @@ -51,6 +51,8 @@ type (
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract
switch {
case evm.chainRules.IsNano:
precompiles = PrecompiledContractsIsNano
case evm.chainRules.IsBerlin:
precompiles = PrecompiledContractsBerlin
case evm.chainRules.IsIstanbul:
Expand Down
28 changes: 23 additions & 5 deletions params/config.go
Expand Up @@ -299,6 +299,7 @@ var (

//TODO
GibbsBlock: nil,
NanoBlock: big.NewInt(21962149),

Parlia: &ParliaConfig{
Period: 3,
Expand All @@ -323,7 +324,7 @@ var (
BrunoBlock: big.NewInt(13837000),
EulerBlock: big.NewInt(19203503),
GibbsBlock: big.NewInt(22800220),

NanoBlock: big.NewInt(23482428),
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
Expand All @@ -347,6 +348,7 @@ var (
BrunoBlock: big.NewInt(400),
EulerBlock: big.NewInt(400),
GibbsBlock: big.NewInt(400),
NanoBlock: nil,

Parlia: &ParliaConfig{
Period: 3,
Expand All @@ -373,6 +375,7 @@ var (
BrunoBlock: big.NewInt(0),
EulerBlock: big.NewInt(0),
GibbsBlock: big.NewInt(0),
NanoBlock: nil,
MuirGlacierBlock: nil,
BerlinBlock: nil, // Don't enable Berlin directly, we're YOLOing it
YoloV3Block: big.NewInt(0),
Expand All @@ -387,16 +390,16 @@ 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, 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), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
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), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, 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}

TestChainConfig = &ChainConfig{big.NewInt(1), 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
TestChainConfig = &ChainConfig{big.NewInt(1), 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int), false)
)

Expand Down Expand Up @@ -490,6 +493,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)

// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
Expand Down Expand Up @@ -540,7 +544,7 @@ func (c *ChainConfig) String() string {
default:
engine = "unknown"
}
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Engine: %v}",
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Engine: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
Expand All @@ -565,6 +569,7 @@ func (c *ChainConfig) String() string {
c.MergeForkBlock,
c.EulerBlock,
c.GibbsBlock,
c.NanoBlock,
engine,
)
}
Expand Down Expand Up @@ -704,6 +709,14 @@ func (c *ChainConfig) IsOnGibbs(num *big.Int) bool {
return configNumEqual(c.GibbsBlock, num)
}

func (c *ChainConfig) IsNano(num *big.Int) bool {
return isForked(c.NanoBlock, num)
}

func (c *ChainConfig) IsOnNano(num *big.Int) bool {
return configNumEqual(c.NanoBlock, num)
}

// CheckCompatible checks whether scheduled fork transitions have been imported
// with a mismatching chain configuration.
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
Expand Down Expand Up @@ -826,6 +839,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
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
}

Expand Down Expand Up @@ -895,6 +911,7 @@ type Rules struct {
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
IsMerge bool
IsNano bool
}

// Rules ensures c's ChainID is not nil.
Expand All @@ -916,5 +933,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules {
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
IsMerge: isMerge,
IsNano: c.IsNano(num),
}
}

0 comments on commit 5b35b39

Please sign in to comment.