mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-11 22:43:47 +00:00
feat(consensus): improve VerifyHeaders for taiko consensus (#238)
* upgrade VerifyHeaders * docs: improve comment wording --------- Co-authored-by: David <david@taiko.xyz>
This commit is contained in:
parent
974b338e20
commit
4f368792dc
2 changed files with 21 additions and 57 deletions
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -87,57 +86,35 @@ func (t *Taiko) VerifyHeader(chain consensus.ChainHeaderReader, header *types.He
|
||||||
// a results channel to retrieve the async verifications (the order is that of
|
// a results channel to retrieve the async verifications (the order is that of
|
||||||
// the input slice).
|
// the input slice).
|
||||||
func (t *Taiko) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) (chan<- struct{}, <-chan error) {
|
func (t *Taiko) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) (chan<- struct{}, <-chan error) {
|
||||||
// Spawn as many workers as allowed threads
|
if len(headers) == 0 {
|
||||||
workers := runtime.GOMAXPROCS(0)
|
return make(chan struct{}), make(chan error, len(headers))
|
||||||
if len(headers) < workers {
|
|
||||||
workers = len(headers)
|
|
||||||
}
|
}
|
||||||
|
abort := make(chan struct{})
|
||||||
|
results := make(chan error, len(headers))
|
||||||
|
unixNow := time.Now().Unix()
|
||||||
|
|
||||||
// Create a task channel and spawn the verifiers
|
|
||||||
var (
|
|
||||||
inputs = make(chan int)
|
|
||||||
done = make(chan int, workers)
|
|
||||||
errors = make([]error, len(headers))
|
|
||||||
abort = make(chan struct{})
|
|
||||||
unixNow = time.Now().Unix()
|
|
||||||
)
|
|
||||||
for i := 0; i < workers; i++ {
|
|
||||||
go func() {
|
|
||||||
for index := range inputs {
|
|
||||||
errors[index] = t.verifyHeaderWorker(chain, headers, index, unixNow)
|
|
||||||
done <- index
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
errorsOut := make(chan error, len(headers))
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(inputs)
|
for i, header := range headers {
|
||||||
var (
|
var parent *types.Header
|
||||||
in, out = 0, 0
|
if i == 0 {
|
||||||
checked = make([]bool, len(headers))
|
parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
|
||||||
inputs = inputs
|
} else if headers[i-1].Hash() == headers[i].ParentHash {
|
||||||
)
|
parent = headers[i-1]
|
||||||
for {
|
}
|
||||||
|
var err error
|
||||||
|
if parent == nil {
|
||||||
|
err = consensus.ErrUnknownAncestor
|
||||||
|
} else {
|
||||||
|
err = t.verifyHeader(chain, header, parent, unixNow)
|
||||||
|
}
|
||||||
select {
|
select {
|
||||||
case inputs <- in:
|
|
||||||
if in++; in == len(headers) {
|
|
||||||
// Reached end of headers. Stop sending to workers.
|
|
||||||
inputs = nil
|
|
||||||
}
|
|
||||||
case index := <-done:
|
|
||||||
for checked[index] = true; checked[out]; out++ {
|
|
||||||
errorsOut <- errors[out]
|
|
||||||
if out == len(headers)-1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case <-abort:
|
case <-abort:
|
||||||
return
|
return
|
||||||
|
case results <- err:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return abort, errorsOut
|
return abort, results
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Taiko) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header, unixNow int64) error {
|
func (t *Taiko) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header, unixNow int64) error {
|
||||||
|
|
@ -193,20 +170,6 @@ func (t *Taiko) verifyHeader(chain consensus.ChainHeaderReader, header, parent *
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Taiko) verifyHeaderWorker(chain consensus.ChainHeaderReader, headers []*types.Header, index int, unixNow int64) error {
|
|
||||||
var parent *types.Header
|
|
||||||
if index == 0 {
|
|
||||||
parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
|
|
||||||
} else if headers[index-1].Hash() == headers[index].ParentHash {
|
|
||||||
parent = headers[index-1]
|
|
||||||
}
|
|
||||||
if parent == nil {
|
|
||||||
return consensus.ErrUnknownAncestor
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.verifyHeader(chain, headers[index], parent, unixNow)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyUncles verifies that the given block's uncles conform to the consensus
|
// VerifyUncles verifies that the given block's uncles conform to the consensus
|
||||||
// rules of a given engine.
|
// rules of a given engine.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
}
|
}
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
|
// CHANGE(taiko): mark the first transaction as anchor transaction.
|
||||||
if i == 0 && p.config.Taiko {
|
if i == 0 && p.config.Taiko {
|
||||||
if err := tx.MarkAsAnchor(); err != nil {
|
if err := tx.MarkAsAnchor(); err != nil {
|
||||||
return nil, nil, 0, err
|
return nil, nil, 0, err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue