Skip to content

Commit f4467d1

Browse files
authored
Implement BEP-592: Non-Consensus Based Block-Level Access List (#3334)
1 parent b448f7f commit f4467d1

37 files changed

+1551
-25
lines changed

cmd/geth/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ var (
146146
utils.MinerRecommitIntervalFlag,
147147
utils.MinerNewPayloadTimeoutFlag, // deprecated
148148
utils.MinerDelayLeftoverFlag,
149+
utils.EnableBALFlag,
149150
// utils.MinerNewPayloadTimeout,
150151
utils.NATFlag,
151152
utils.NoDiscoverFlag,

cmd/utils/flags.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ var (
182182
Usage: "Chapel network: pre-configured Proof-of-Stake-Authority BSC test network",
183183
Category: flags.EthCategory,
184184
}
185+
EnableBALFlag = &cli.BoolFlag{
186+
Name: "enablebal",
187+
Usage: "Enable block access list feature, validator will generate BAL for each block",
188+
Category: flags.EthCategory,
189+
}
185190
// Dev mode
186191
DeveloperFlag = &cli.BoolFlag{
187192
Name: "dev",
@@ -1743,6 +1748,9 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
17431748
if ctx.IsSet(DisableSnapProtocolFlag.Name) {
17441749
cfg.DisableSnapProtocol = ctx.Bool(DisableSnapProtocolFlag.Name)
17451750
}
1751+
if ctx.IsSet(EnableBALFlag.Name) {
1752+
cfg.EnableBAL = ctx.Bool(EnableBALFlag.Name)
1753+
}
17461754
if ctx.IsSet(RangeLimitFlag.Name) {
17471755
cfg.RangeLimit = ctx.Bool(RangeLimitFlag.Name)
17481756
}
@@ -2042,6 +2050,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
20422050
if ctx.IsSet(CacheNoPrefetchFlag.Name) {
20432051
cfg.NoPrefetch = ctx.Bool(CacheNoPrefetchFlag.Name)
20442052
}
2053+
if ctx.IsSet(EnableBALFlag.Name) {
2054+
cfg.EnableBAL = ctx.Bool(EnableBALFlag.Name)
2055+
}
20452056
// Read the value from the flag no matter if it's set or not.
20462057
cfg.Preimages = ctx.Bool(CachePreimagesFlag.Name)
20472058
if cfg.NoPruning && !cfg.Preimages {
@@ -2697,6 +2708,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
26972708
options := &core.BlockChainConfig{
26982709
TrieCleanLimit: ethconfig.Defaults.TrieCleanCache,
26992710
NoPrefetch: ctx.Bool(CacheNoPrefetchFlag.Name),
2711+
EnableBAL: ctx.Bool(EnableBALFlag.Name),
27002712
TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache,
27012713
ArchiveMode: ctx.String(GCModeFlag.Name) == "archive",
27022714
TrieTimeLimit: ethconfig.Defaults.TrieTimeout,

consensus/beacon/consensus.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,15 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash {
491491
return beacon.ethone.SealHash(header)
492492
}
493493

494+
func (beacon *Beacon) SignBAL(blockAccessList *types.BlockAccessListEncode) error {
495+
return nil
496+
}
497+
498+
// VerifyBAL verifies the BAL of the block
499+
func (beacon *Beacon) VerifyBAL(block *types.Block, bal *types.BlockAccessListEncode) error {
500+
return nil
501+
}
502+
494503
// CalcDifficulty is the difficulty adjustment algorithm. It returns
495504
// the difficulty that a new block should have when created at time
496505
// given the parent block's time and difficulty.

consensus/clique/clique.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,3 +787,11 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
787787
panic("can't encode: " + err.Error())
788788
}
789789
}
790+
791+
func (c *Clique) SignBAL(bal *types.BlockAccessListEncode) error {
792+
return nil
793+
}
794+
795+
func (c *Clique) VerifyBAL(block *types.Block, bal *types.BlockAccessListEncode) error {
796+
return nil
797+
}

consensus/consensus.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ type Engine interface {
136136
// SealHash returns the hash of a block prior to it being sealed.
137137
SealHash(header *types.Header) common.Hash
138138

139+
// SignBAL signs the BAL of the block
140+
SignBAL(blockAccessList *types.BlockAccessListEncode) error
141+
142+
// VerifyBAL verifies the BAL of the block
143+
VerifyBAL(block *types.Block, bal *types.BlockAccessListEncode) error
144+
139145
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
140146
// that a new block should have.
141147
CalcDifficulty(chain ChainHeaderReader, time uint64, parent *types.Header) *big.Int

consensus/ethash/ethash.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,11 @@ func (ethash *Ethash) Close() error {
7676
func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
7777
panic("ethash (pow) sealing not supported any more")
7878
}
79+
80+
func (ethash *Ethash) SignBAL(bal *types.BlockAccessListEncode) error {
81+
return nil
82+
}
83+
84+
func (ethash *Ethash) VerifyBAL(block *types.Block, bal *types.BlockAccessListEncode) error {
85+
return nil
86+
}

consensus/parlia/parlia.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,71 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res
17551755
return nil
17561756
}
17571757

1758+
func (p *Parlia) SignBAL(blockAccessList *types.BlockAccessListEncode) error {
1759+
p.lock.RLock()
1760+
val, signFn := p.val, p.signFn
1761+
p.lock.RUnlock()
1762+
1763+
data, err := rlp.EncodeToBytes([]interface{}{blockAccessList.Version, blockAccessList.Number, blockAccessList.Hash, blockAccessList.Accounts})
1764+
if err != nil {
1765+
log.Error("Encode to bytes failed when sealing", "err", err)
1766+
return errors.New("encode to bytes failed")
1767+
}
1768+
1769+
if len(data) > int(params.MaxBALSize) {
1770+
log.Error("data is too large", "dataSize", len(data), "maxSize", params.MaxBALSize)
1771+
return errors.New("data is too large")
1772+
}
1773+
1774+
sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, data)
1775+
if err != nil {
1776+
log.Error("Sign for the block header failed when sealing", "err", err)
1777+
return errors.New("sign for the block header failed")
1778+
}
1779+
1780+
copy(blockAccessList.SignData, sig)
1781+
return nil
1782+
}
1783+
1784+
func (p *Parlia) VerifyBAL(block *types.Block, bal *types.BlockAccessListEncode) error {
1785+
if bal.Version != 0 {
1786+
log.Error("invalid BAL version", "version", bal.Version)
1787+
return errors.New("invalid BAL version")
1788+
}
1789+
1790+
if len(bal.SignData) != 65 {
1791+
log.Error("invalid BAL signature", "signatureSize", len(bal.SignData))
1792+
return errors.New("invalid BAL signature")
1793+
}
1794+
1795+
// Recover the public key and the Ethereum address
1796+
data, err := rlp.EncodeToBytes([]interface{}{bal.Version, block.Number(), block.Hash(), bal.Accounts})
1797+
if err != nil {
1798+
log.Error("encode to bytes failed", "err", err)
1799+
return errors.New("encode to bytes failed")
1800+
}
1801+
1802+
if len(data) > int(params.MaxBALSize) {
1803+
log.Error("data is too large", "dataSize", len(data), "maxSize", params.MaxBALSize)
1804+
return errors.New("data is too large")
1805+
}
1806+
1807+
pubkey, err := crypto.Ecrecover(crypto.Keccak256(data), bal.SignData)
1808+
if err != nil {
1809+
return err
1810+
}
1811+
var pubkeyAddr common.Address
1812+
copy(pubkeyAddr[:], crypto.Keccak256(pubkey[1:])[12:])
1813+
1814+
signer := block.Header().Coinbase
1815+
if signer != pubkeyAddr {
1816+
log.Error("BAL signer mismatch", "signer", signer, "pubkeyAddr", pubkeyAddr, "bal.Number", bal.Number, "bal.Hash", bal.Hash)
1817+
return errors.New("signer mismatch")
1818+
}
1819+
1820+
return nil
1821+
}
1822+
17581823
func (p *Parlia) shouldWaitForCurrentBlockProcess(chain consensus.ChainHeaderReader, header *types.Header, snap *Snapshot) bool {
17591824
if header.Difficulty.Cmp(diffInTurn) == 0 {
17601825
return false

0 commit comments

Comments
 (0)