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

Full BSC support with validator mode #3233

Merged
merged 88 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
069309d
migrated consensus and chain config files for bsc support
dmitry123 Nov 23, 2021
d7ceb9e
migrated more files from bsc
dmitry123 Nov 24, 2021
28808e5
fixed consensus crashing
dmitry123 Nov 25, 2021
9538b92
updated erigon lib for parlia snapshot prefix
dmitry123 Nov 25, 2021
935ed6c
added staticpeers for bsc
dmitry123 Nov 25, 2021
109f32b
[+] added system contracts
dmitry123 Nov 25, 2021
6a86981
migrated system contract calls
dmitry123 Nov 25, 2021
5b52c6b
[*] fixed bug with returning mutable balance object
dmitry123 Nov 26, 2021
1401bb4
[*] fixed tendermint deps
dmitry123 Nov 26, 2021
1cd6c41
[+] added some logs
dmitry123 Nov 26, 2021
18bd624
[+] enabled bsc forks
dmitry123 Nov 29, 2021
3e94431
Fix call sys contract gas calculation
convexman Nov 29, 2021
37a0d9b
[*] fixed executing system transactions
dmitry123 Nov 29, 2021
b0c1fdf
[*] enabled receipt hash, gas and bloom filter checks
dmitry123 Nov 29, 2021
5feb33a
[-] removed some logging scripts
dmitry123 Nov 30, 2021
a49426f
[*] fixed bug with commiting dirty inter block state state after syst…
dmitry123 Dec 3, 2021
b6b2734
[+] added chapel and rialto testnet support
dmitry123 Dec 6, 2021
6b3901d
[*] fixed chapel allocs
dmitry123 Dec 6, 2021
7fbca56
[-] removed 6 mil block limit for headers sync
dmitry123 Dec 6, 2021
5a31429
Fix hardforks on chapel and other testnets
convexman Dec 6, 2021
84c564e
Merge branch 'bsc' of github.com:Ankr-network/erigon-for-bsc into bsc
dmitry123 Dec 6, 2021
93f943f
Merge remote-tracking branch 'origin/bsc' into bsc-ankr
dmitry123 Dec 7, 2021
203fbb3
[*] fixed header sync issue after merge
dmitry123 Dec 7, 2021
90261f3
[*] tiny code cleanup
dmitry123 Dec 7, 2021
54c7407
[-] removed some comments
dmitry123 Dec 9, 2021
6c7fac0
[*] increased mdbx map size to 4 TB
dmitry123 Dec 9, 2021
2eb25c0
[*] increased max chaindata size to 6 tb
dmitry123 Dec 14, 2021
469b9aa
[*] bring more compatibility with origin erigon and some code cleanup
dmitry123 Dec 15, 2021
d187f84
[+] added support of validator mode for BSC chain
dmitry123 Dec 15, 2021
90236f7
[*] enable private key load for bsc, rialto and chapel chains
dmitry123 Dec 15, 2021
b914105
[*] fixed running BSC validator node
dmitry123 Dec 15, 2021
8150ca5
Fix the branch list
j75689 Dec 16, 2021
f1298b8
[*] tiny fixes for linter
dmitry123 Dec 16, 2021
5d43735
Merge pull request #4 from j75689/fix/ci_workflows
j75689 Dec 16, 2021
c764b58
[*] formatted imports for core and parlia packages
dmitry123 Dec 16, 2021
73ec558
[*] fixed import rules in other files
dmitry123 Dec 16, 2021
c7e2c2b
Revert "[*] formatted imports for core and parlia packages"
dmitry123 Dec 16, 2021
d555839
[*] changed import rules in more packages
dmitry123 Dec 16, 2021
2345b38
Merge pull request #1 from binance-chain/bsc-ankr
j75689 Dec 16, 2021
13dce95
Merge remote-tracking branch 'origin/bsc' into bsc-validator-support
dmitry123 Dec 16, 2021
3544df3
[*] fixed type mismatch in hack command
dmitry123 Dec 16, 2021
b4ed564
[*] fixed crash on new epoch, enabled bootstrap flags
dmitry123 Dec 16, 2021
798076d
[*] fixed linter errors
dmitry123 Dec 16, 2021
de3b1c6
[*] fixed missing err check for syscalls
dmitry123 Dec 16, 2021
62dd8de
[*] now BSC implementation is fully compatible with erigon original s…
dmitry123 Dec 17, 2021
d195cd0
Merge pull request #5 from binance-chain/bsc-parlia-hotfix
dmitry123 Dec 17, 2021
acd5d04
Merge remote-tracking branch 'origin/bsc' into bsc-erigon-compatibility
dmitry123 Dec 17, 2021
6ebcb28
Merge pull request #6 from binance-chain/bsc-erigon-compatibility
dmitry123 Dec 17, 2021
7b07e99
Merge remote-tracking branch 'origin/bsc' into bsc-validator-support
dmitry123 Dec 17, 2021
c897053
Revert "Add chain config and CLI changes for Binance Smart Chain supp…
dmitry123 Dec 17, 2021
8d22c97
Revert "Add Parlia consensus engine for Binance Smart Chain support (…
dmitry123 Dec 17, 2021
8cc837f
Merge branch 'bsc' into erigon-bsc-merge
dmitry123 Dec 17, 2021
9285a83
Merge branch 'bsc-validator-support' into erigon-bsc-merge
dmitry123 Dec 17, 2021
eb3e171
[*] fixed several issues after merge
dmitry123 Dec 17, 2021
660ff21
[*] fixed integration compilation
dmitry123 Dec 17, 2021
3245254
Merge pull request #3 from binance-chain/bsc-validator-support
dmitry123 Dec 17, 2021
383c52d
Merge remote-tracking branch 'origin/bsc' into erigon-bsc-merge
dmitry123 Dec 17, 2021
2e1c74c
Merge pull request #7 from binance-chain/erigon-bsc-merge
dmitry123 Dec 17, 2021
ce1f76b
Revert "Fix the branch list"
dmitry123 Dec 17, 2021
080c106
[-] removed receipt repair migration
dmitry123 Dec 17, 2021
d9423ef
Merge branch 'erigon-bsc-merge' into bsc
dmitry123 Dec 19, 2021
63983ae
Merge remote-tracking branch 'bsc-remote/bsc' into bsc
dmitry123 Dec 19, 2021
05b1a52
[*] fixed parlia fork numbers output
dmitry123 Dec 22, 2021
ddabb23
Merge remote-tracking branch 'erigon/devel' into bsc
dmitry123 Dec 22, 2021
2c5a094
Merge branch 'devel' into bsc
dmitry123 Dec 23, 2021
bff5928
[*] bring more devel compatibility, fixed bsc address list for access…
dmitry123 Dec 23, 2021
66ccbfd
[*] fixed bug with commiting state transition for bad blocks in BSC
dmitry123 Dec 23, 2021
e338d7c
[*] fixed bsc changes apply for integration command and updated confi…
dmitry123 Dec 24, 2021
91b3637
[*] fixed bug with applying bsc forks for chapel and rialto testnet c…
dmitry123 Dec 23, 2021
37b25da
Merge remote-tracking branch 'erigon/devel' into bsc
dmitry123 Dec 27, 2021
c226668
Merge remote-tracking branch 'erigon/devel' into bsc
dmitry123 Jan 10, 2022
454f2f8
Merge remote-tracking branch 'erigon/devel' into bsc
dmitry123 Jan 11, 2022
2be4744
Fix compilation errors in hack.go
Jan 11, 2022
957739f
Fix lint
Jan 11, 2022
252a7fb
reset changes in erigon-snapshots to devel
Jan 11, 2022
d19c86d
Remove unrelated changes
Jan 11, 2022
00891e7
Fix embed
Jan 11, 2022
b6c52ce
Remove more unrelated changes
Jan 12, 2022
01dd598
Merge remote-tracking branch 'origin/devel' into bsc
Jan 12, 2022
825a031
Remove more unrelated changes
Jan 12, 2022
5120313
Restore clique and aura miner config
Jan 12, 2022
78bdc3b
Refactor interfaces not to use slice pointers
Jan 12, 2022
df6f05d
Refactor parlia functions to return tx and receipt instead of dealing…
Jan 13, 2022
4021cf3
Fix for header panic
Jan 13, 2022
8fea85e
Merge remote-tracking branch 'origin/devel' into bsc
Jan 13, 2022
809003e
Fix lint, restore system contract addresses
Jan 13, 2022
900aef2
Remove more unrelated changes, unify GatherForks
Jan 13, 2022
27824c0
Merge remote-tracking branch 'origin/devel' into bsc
Jan 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[*] bring more compatibility with origin erigon and some code cleanup
  • Loading branch information
dmitry123 committed Dec 15, 2021
commit 469b9aa227d809cb2fd813e737d4c4caefe9130e
2 changes: 1 addition & 1 deletion consensus/aura/aura.go
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ func callBlockRewardAbi(contractAddr common.Address, syscall consensus.SystemCal
if err != nil {
panic(err)
}
_, out, err := syscall(contractAddr, packed)
out, err := syscall(contractAddr, packed)
if err != nil {
panic(err)
}
Expand Down
4 changes: 2 additions & 2 deletions consensus/aura/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ func (s *ValidatorSafeContract) getListSyscall(caller consensus.SystemCall) (*Si
if err != nil {
panic(err)
}
_, out, err := caller(s.contractAddress, packed)
out, err := caller(s.contractAddress, packed)
if err != nil {
panic(err)
}
Expand All @@ -651,7 +651,7 @@ func (s *ValidatorSafeContract) genesisEpochData(header *types.Header, call cons

func (s *ValidatorSafeContract) onEpochBegin(firstInEpoch bool, header *types.Header, caller consensus.SystemCall) error {
data := common.FromHex("75286211")
_, _, err := caller(s.contractAddress, data)
_, err := caller(s.contractAddress, data)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type EpochReader interface {
FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash common.Hash, transitionProof []byte, err error)
}

type SystemCall func(contract common.Address, data []byte) (gasUsed uint64, returnData []byte, err error)
type SystemCall func(contract common.Address, data []byte) ([]byte, error)
type Call func(contract common.Address, data []byte) ([]byte, error)

// Engine is an algorithm agnostic consensus engine.
Expand Down
45 changes: 31 additions & 14 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/ledgerwatch/erigon/core/systemcontracts"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/types/accounts"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/rlp"
Expand Down Expand Up @@ -823,7 +824,7 @@ func (p *Parlia) getCurrentValidators(header *types.Header, state *state.IntraBl
// call
msgData := (hexutil.Bytes)(data)
toAddress := common.HexToAddress(systemcontracts.ValidatorContract)
_, returnData, err := core.SysCallContract(header.Coinbase, toAddress, msgData[:], *p.chainConfig, state, header, p, u256.Num0)
_, returnData, err := systemCall(header.Coinbase, toAddress, msgData[:], *p.chainConfig, state, header, p, u256.Num0)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1000,7 +1001,7 @@ func (p *Parlia) applyTransaction(
*receivedTxs = (*receivedTxs)[1:]
}
ibs.Prepare(expectedTx.Hash(), common.Hash{}, len(*txs))
gasUsed, _, err := core.SysCallContract(from, to, data, *p.chainConfig, ibs, header, p, value)
gasUsed, _, err := systemCall(from, to, data, *p.chainConfig, ibs, header, p, value)
*txs = append(*txs, expectedTx)
*usedGas += gasUsed
receipt := types.NewReceipt(false, *usedGas)
Expand All @@ -1020,16 +1021,32 @@ func (p *Parlia) applyTransaction(
return nil
}

// chain context
type chainContext struct {
Chain consensus.ChainHeaderReader
parlia consensus.Engine
}

func (c chainContext) Engine() consensus.Engine {
return c.parlia
}

func (c chainContext) GetHeader(hash common.Hash, number uint64) *types.Header {
return c.Chain.GetHeader(hash, number)
func systemCall(from, contract common.Address, data []byte, chainConfig params.ChainConfig, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine, value *uint256.Int) (gasUsed uint64, returnData []byte, err error) {
if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(ibs)
}
msg := types.NewMessage(
from,
&contract,
0, value,
math.MaxUint64/2, u256.Num0,
nil, nil,
data, nil, false,
)
vmConfig := vm.Config{NoReceipts: true}
// Create a new context to be used in the EVM environment
blockContext := core.NewEVMBlockContext(header, nil, engine, &from, nil)
evm := vm.NewEVM(blockContext, core.NewEVMTxContext(msg), ibs, &chainConfig, vmConfig)
ret, leftOverGas, err := evm.Call(
vm.AccountRef(msg.From()),
*msg.To(),
msg.Data(),
msg.Gas(),
msg.Value(),
false,
)
if err != nil {
return 0, nil, err
}
return msg.Gas() - leftOverGas, ret, nil
}
58 changes: 23 additions & 35 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ package core
import (
"encoding/json"
"fmt"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon/common/math"
"github.com/ledgerwatch/erigon/core/systemcontracts"
"os"
"time"
Expand Down Expand Up @@ -187,36 +185,30 @@ func ExecuteBlockEphemerally(
return receipts, nil
}

func SysCallContract(from, contract common.Address, data []byte, chainConfig params.ChainConfig, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine, value *uint256.Int) (gasUsed uint64, returnData []byte, err error) {
func SysCallContract(contract common.Address, data []byte, chainConfig params.ChainConfig, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine) (result []byte, err error) {
gp := new(GasPool).AddGas(50_000_000)

if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(ibs)
}

msg := types.NewMessage(
from,
state.SystemAddress,
&contract,
0, value,
math.MaxUint64/2, u256.Num0,
0, u256.Num0,
50_000_000, u256.Num0,
nil, nil,
data, nil, false,
)
vmConfig := vm.Config{NoReceipts: true}
// Create a new context to be used in the EVM environment
blockContext := NewEVMBlockContext(header, nil, engine, &from, nil)
blockContext := NewEVMBlockContext(header, nil, engine, &state.SystemAddress, nil)
evm := vm.NewEVM(blockContext, NewEVMTxContext(msg), ibs, &chainConfig, vmConfig)
ret, leftOverGas, err := evm.Call(
vm.AccountRef(msg.From()),
*msg.To(),
msg.Data(),
msg.Gas(),
msg.Value(),
false,
)

//res, err := ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */)
res, err := ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */)
if err != nil {
return 0, nil, err
return nil, err
}
return msg.Gas() - leftOverGas, ret, nil
return res.ReturnData, nil
}

// from the null sender, with 50M gas.
Expand Down Expand Up @@ -256,21 +248,21 @@ func CallContractTx(contract common.Address, data []byte, ibs *state.IntraBlockS
}

func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateReader, header *types.Header, txs types.Transactions, uncles []*types.Header, stateWriter state.WriterWithChangeSets, cc *params.ChainConfig, ibs *state.IntraBlockState, receipts *types.Receipts, e consensus.EpochReader, headerReader consensus.ChainHeaderReader, gasUsed *uint64) (*types.Block, error) {
//ibs.Print(cc.Rules(header.Number.Uint64()))
//fmt.Printf("====tx processing end====\n")
//if posa := engine.(consensus.PoSA); posa != nil {
// posa.FinalizeAndAssemble()
//}


// We're doing this hack for BSC to avoid changing consensus interfaces. BSC modifies txs and receipts by appending
// system transactions, and they increase used gas and write cumulative gas to system receipts, that's why we need
// to deduct system gas before. This line is equal to "blockGas-systemGas", but since we don't know how much gas is
// used by system transactions we just override. Of course, we write used by block gas back. It also always true
// that used gas by block is always equal to original's block header gas, and it's checked by receipts root verification
// otherwise it causes block verification error.
header.GasUsed = *gasUsed
block, err := engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, *receipts, e, headerReader, nil, nil)
block, err := engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, *receipts, e, headerReader, func(contract common.Address, data []byte) ([]byte, error) {
return SysCallContract(contract, data, *cc, ibs, header, engine)
}, nil)
if err != nil {
return nil, err
}
*gasUsed = header.GasUsed
//fmt.Printf("====finalize start %d====\n", header.Number.Uint64())
//ibs.Print(cc.Rules(header.Number.Uint64()))
//fmt.Printf("====finalize end====\n")

var originalSystemAcc *accounts.Account

Expand Down Expand Up @@ -305,12 +297,8 @@ func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateRead

func InitializeBlockExecution(engine consensus.Engine, chain consensus.ChainHeaderReader, epochReader consensus.EpochReader, header *types.Header, txs types.Transactions, uncles []*types.Header, cc *params.ChainConfig, ibs *state.IntraBlockState) error {
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
engine.Initialize(cc, chain, epochReader, header, txs, uncles, func(contract common.Address, data []byte) (gasUsed uint64, returnData []byte, err error) {
panic("not implemented")
engine.Initialize(cc, chain, epochReader, header, txs, uncles, func(contract common.Address, data []byte) ([]byte, error) {
return SysCallContract(contract, data, *cc, ibs, header, engine)
})
//fmt.Printf("====InitializeBlockExecution start %d====\n", header.Number.Uint64())
//ibs.Print(cc.Rules(header.Number.Uint64()))
//fmt.Printf("====InitializeBlockExecution end====\n")

return nil
}
4 changes: 0 additions & 4 deletions core/state/intra_block_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -776,10 +776,6 @@ func (sdb *IntraBlockState) CommitBlock(chainRules params.Rules, stateWriter Sta
return nil
}

func (sdb *IntraBlockState) GetStateWriter() StateWriter {
return sdb.stateReader.(StateWriter)
}

func (sdb *IntraBlockState) Print(chainRules params.Rules) {
for addr, stateObject := range sdb.stateObjects {
_, isDirty := sdb.stateObjectsDirty[addr]
Expand Down
1 change: 1 addition & 0 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ func (so *stateObject) CodeHash() []byte {
}

func (so *stateObject) Balance() *uint256.Int {
// It's better to return copy of balance, otherwise it might cause shadow changes
return so.data.Balance.Clone()
}

Expand Down
6 changes: 5 additions & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ func applyTransaction(config *params.ChainConfig, gp *GasPool, statedb *state.In
// Update the evm with the new transaction context.
evm.Reset(txContext, statedb)

result, err := ApplyMessage(evm, msg, gp, true /* refunds */, true /* gasBailout */)
gasBailout := false
if config.Parlia != nil {
gasBailout = true
}
result, err := ApplyMessage(evm, msg, gp, true /* refunds */, gasBailout /* gasBailout */)
if err != nil {
return nil, nil, err
}
Expand Down
2 changes: 0 additions & 2 deletions core/types/transaction_signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ func MakeSigner(config *params.ChainConfig, blockNumber uint64) *Signer {
return &signer
}



func MakeFrontierSigner() *Signer {
var signer Signer
signer.maleable = true
Expand Down
12 changes: 12 additions & 0 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
// contracts used in the Istanbul release.
var PrecompiledContractsIstanbul = 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{eip2565: false},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
}

var PrecompiledContractsIstanbulForBSC = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
Expand Down
6 changes: 5 additions & 1 deletion core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
case evm.chainRules.IsBerlin:
precompiles = PrecompiledContractsBerlin
case evm.chainRules.IsIstanbul:
precompiles = PrecompiledContractsIstanbul
if evm.chainRules.IsParlia {
precompiles = PrecompiledContractsIstanbulForBSC
} else {
precompiles = PrecompiledContractsIstanbul
}
case evm.chainRules.IsByzantium:
precompiles = PrecompiledContractsByzantium
default:
Expand Down
3 changes: 2 additions & 1 deletion params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ type Rules struct {
ChainID *big.Int
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
IsBerlin, IsLondon, IsParlia bool
}

// Rules ensures c's ChainID is not nil.
Expand All @@ -918,5 +918,6 @@ func (c *ChainConfig) Rules(num uint64) Rules {
IsIstanbul: c.IsIstanbul(num),
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
IsParlia: c.Parlia != nil,
}
}