mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-30 00:23:46 +00:00
pull changes
This commit is contained in:
commit
793f8e1292
31 changed files with 613 additions and 229 deletions
23
.github/CODEOWNERS
vendored
23
.github/CODEOWNERS
vendored
|
|
@ -1,23 +0,0 @@
|
|||
# Lines starting with '#' are comments.
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
|
||||
accounts/usbwallet @karalabe
|
||||
accounts/scwallet @gballet
|
||||
accounts/abi @gballet @MariusVanDerWijden
|
||||
cmd/clef @holiman
|
||||
cmd/puppeth @karalabe
|
||||
consensus @karalabe
|
||||
core/ @karalabe @holiman @rjl493456442
|
||||
eth/ @karalabe @holiman @rjl493456442
|
||||
eth/catalyst/ @gballet
|
||||
graphql/ @gballet
|
||||
les/ @zsfelfoldi @rjl493456442
|
||||
light/ @zsfelfoldi @rjl493456442
|
||||
mobile/ @karalabe @ligi
|
||||
node/ @fjl @renaynay
|
||||
p2p/ @fjl @zsfelfoldi
|
||||
rpc/ @fjl @holiman
|
||||
p2p/simulations @fjl
|
||||
p2p/protocols @fjl
|
||||
p2p/testing @fjl
|
||||
signer/ @holiman
|
||||
2
.github/matic-cli-config.yml
vendored
2
.github/matic-cli-config.yml
vendored
|
|
@ -8,4 +8,4 @@ numOfNonValidators: 0
|
|||
ethURL: http://ganache:9545
|
||||
devnetType: docker
|
||||
borDockerBuildContext: "../../bor"
|
||||
heimdallDockerBuildContext: "https://github.com/maticnetwork/heimdall.git#v0.3.0-dev"
|
||||
heimdallDockerBuildContext: "https://github.com/maticnetwork/heimdall.git#develop"
|
||||
|
|
|
|||
44
.github/pull_request_template.md
vendored
Normal file
44
.github/pull_request_template.md
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Description
|
||||
|
||||
Please provide a detailed description of what was done in this PR
|
||||
|
||||
# Changes
|
||||
|
||||
- [ ] Bugfix (non-breaking change that solves an issue)
|
||||
- [ ] Hotfix (change that solves an urgent issue, and requires immediate attention)
|
||||
- [ ] New feature (non-breaking change that adds functionality)
|
||||
- [ ] Breaking change (change that is not backwards-compatible and/or changes current functionality)
|
||||
|
||||
# Breaking changes
|
||||
|
||||
Please complete this section if any breaking changes have been made, otherwise delete it
|
||||
|
||||
# Checklist
|
||||
|
||||
- [ ] I have added at least 2 reviewer or the whole pos-v1 team
|
||||
- [ ] I have added sufficient documentation in code
|
||||
- [ ] I will be resolving comments - if any - by pushing each fix in a separate commit and linking the commit hash in the comment reply
|
||||
|
||||
# Cross repository changes
|
||||
|
||||
- [ ] This PR requires changes to heimdall
|
||||
- In case link the PR here:
|
||||
- [ ] This PR requires changes to matic-cli
|
||||
- In case link the PR here:
|
||||
|
||||
## Testing
|
||||
|
||||
- [ ] I have added unit tests
|
||||
- [ ] I have added tests to CI
|
||||
- [ ] I have tested this code manually on local environment
|
||||
- [ ] I have tested this code manually on remote devnet using express-cli
|
||||
- [ ] I have tested this code manually on mumbai
|
||||
- [ ] I have created new e2e tests into express-cli
|
||||
|
||||
### Manual tests
|
||||
|
||||
Please complete this section with the steps you performed if you ran manual tests for this functionality, otherwise delete it
|
||||
|
||||
# Additional comments
|
||||
|
||||
Please post additional comments in this section if you have them, otherwise delete it
|
||||
|
|
@ -10,6 +10,7 @@ datadir = "/var/lib/bor/data"
|
|||
syncmode = "full"
|
||||
# gcmode = "full"
|
||||
# snapshot = true
|
||||
# "bor.logs" = false
|
||||
# ethstats = ""
|
||||
|
||||
# ["eth.requiredblocks"]
|
||||
|
|
@ -134,4 +135,4 @@ syncmode = "full"
|
|||
|
||||
# [developer]
|
||||
# dev = false
|
||||
# period = 0
|
||||
# period = 0
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package t8ntool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
|
@ -188,7 +189,7 @@ func (i *bbInput) sealEthash(block *types.Block) (*types.Block, error) {
|
|||
// If the testmode is used, the sealer will return quickly, and complain
|
||||
// "Sealing result is not read by miner" if it cannot write the result.
|
||||
results := make(chan *types.Block, 1)
|
||||
if err := engine.Seal(nil, block, results, nil); err != nil {
|
||||
if err := engine.Seal(context.Background(), nil, block, results, nil); err != nil {
|
||||
panic(fmt.Sprintf("failed to seal block: %v", err))
|
||||
}
|
||||
found := <-results
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
|
||||
txIndex++
|
||||
}
|
||||
|
||||
statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber))
|
||||
// Add mining reward?
|
||||
if miningReward > 0 {
|
||||
|
|
|
|||
96
common/tracing/context.go
Normal file
96
common/tracing/context.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
package tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type tracerKey struct{}
|
||||
|
||||
type Option func(context.Context, trace.Span)
|
||||
|
||||
func WithTracer(ctx context.Context, tr trace.Tracer) context.Context {
|
||||
return context.WithValue(ctx, tracerKey{}, tr)
|
||||
}
|
||||
|
||||
func FromContext(ctx context.Context) trace.Tracer {
|
||||
tr, _ := ctx.Value(tracerKey{}).(trace.Tracer)
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
func StartSpan(ctx context.Context, snapName string) (context.Context, trace.Span) {
|
||||
tr := FromContext(ctx)
|
||||
|
||||
if tr == nil {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
ctx, span := tr.Start(ctx, snapName)
|
||||
ctx = WithTracer(ctx, tr)
|
||||
|
||||
return ctx, span
|
||||
}
|
||||
|
||||
func EndSpan(span trace.Span) {
|
||||
if span != nil {
|
||||
span.End()
|
||||
}
|
||||
}
|
||||
|
||||
func Trace(ctx context.Context, spanName string) (context.Context, trace.Span) {
|
||||
tr := FromContext(ctx)
|
||||
|
||||
if tr == nil {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
return tr.Start(ctx, spanName)
|
||||
}
|
||||
|
||||
func Exec(ctx context.Context, spanName string, opts ...Option) {
|
||||
var span trace.Span
|
||||
|
||||
tr := FromContext(ctx)
|
||||
|
||||
if tr != nil {
|
||||
ctx, span = tr.Start(ctx, spanName)
|
||||
}
|
||||
|
||||
for _, optFn := range opts {
|
||||
optFn(ctx, span)
|
||||
}
|
||||
|
||||
if tr != nil {
|
||||
span.End()
|
||||
}
|
||||
}
|
||||
|
||||
func WithTime(fn func(context.Context, trace.Span)) Option {
|
||||
return func(ctx context.Context, span trace.Span) {
|
||||
ElapsedTime(ctx, span, "elapsed", fn)
|
||||
}
|
||||
}
|
||||
|
||||
func ElapsedTime(ctx context.Context, span trace.Span, msg string, fn func(context.Context, trace.Span)) {
|
||||
var now time.Time
|
||||
|
||||
if span != nil {
|
||||
now = time.Now()
|
||||
}
|
||||
|
||||
fn(ctx, span)
|
||||
|
||||
if span != nil {
|
||||
span.SetAttributes(attribute.Int(msg, int(time.Since(now).Milliseconds())))
|
||||
}
|
||||
}
|
||||
|
||||
func SetAttributes(span trace.Span, kvs ...attribute.KeyValue) {
|
||||
if span != nil {
|
||||
span.SetAttributes(kvs...)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package beacon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
|
@ -170,10 +171,11 @@ func (beacon *Beacon) VerifyUncles(chain consensus.ChainReader, block *types.Blo
|
|||
// verifyHeader checks whether a header conforms to the consensus rules of the
|
||||
// stock Ethereum consensus engine. The difference between the beacon and classic is
|
||||
// (a) The following fields are expected to be constants:
|
||||
// - difficulty is expected to be 0
|
||||
// - nonce is expected to be 0
|
||||
// - unclehash is expected to be Hash(emptyHeader)
|
||||
// - difficulty is expected to be 0
|
||||
// - nonce is expected to be 0
|
||||
// - unclehash is expected to be Hash(emptyHeader)
|
||||
// to be the desired constants
|
||||
//
|
||||
// (b) the timestamp is not verified anymore
|
||||
// (c) the extradata is limited to 32 bytes
|
||||
func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header) error {
|
||||
|
|
@ -278,11 +280,11 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
|
|||
|
||||
// FinalizeAndAssemble implements consensus.Engine, setting the final state and
|
||||
// assembling the block.
|
||||
func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
func (beacon *Beacon) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
// FinalizeAndAssemble is different with Prepare, it can be used in both block
|
||||
// generation and verification. So determine the consensus rules by header type.
|
||||
if !beacon.IsPoSHeader(header) {
|
||||
return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts)
|
||||
return beacon.ethone.FinalizeAndAssemble(ctx, chain, header, state, txs, uncles, receipts)
|
||||
}
|
||||
// Finalize and assemble the block
|
||||
beacon.Finalize(chain, header, state, txs, uncles)
|
||||
|
|
@ -294,9 +296,9 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
|
|||
//
|
||||
// Note, the method returns immediately and will send the result async. More
|
||||
// than one result may also be returned depending on the consensus algorithm.
|
||||
func (beacon *Beacon) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
func (beacon *Beacon) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
if !beacon.IsPoSHeader(block.Header()) {
|
||||
return beacon.ethone.Seal(chain, block, results, stop)
|
||||
return beacon.ethone.Seal(ctx, chain, block, results, stop)
|
||||
}
|
||||
// The seal verification is done by the external consensus engine,
|
||||
// return directly without pushing any block back. In another word
|
||||
|
|
|
|||
|
|
@ -16,10 +16,13 @@ import (
|
|||
"time"
|
||||
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/tracing"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/bor/api"
|
||||
"github.com/ethereum/go-ethereum/consensus/bor/clerk"
|
||||
|
|
@ -735,9 +738,9 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header,
|
|||
|
||||
headerNumber := header.Number.Uint64()
|
||||
|
||||
if IsSprintStart(headerNumber, c.config.Sprint) {
|
||||
ctx := context.Background()
|
||||
ctx := context.Background()
|
||||
|
||||
if IsSprintStart(headerNumber, c.config.Sprint) {
|
||||
cx := statefull.ChainContext{Chain: chain, Bor: c}
|
||||
// check and commit span
|
||||
if err := c.checkAndCommitSpan(ctx, state, header, cx); err != nil {
|
||||
|
|
@ -804,26 +807,35 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.State
|
|||
|
||||
// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
|
||||
// nor block rewards given, and returns the final block.
|
||||
func (c *Bor) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, _ []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
var stateSyncData []*types.StateSyncData
|
||||
func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
finalizeCtx, finalizeSpan := tracing.StartSpan(ctx, "bor.FinalizeAndAssemble")
|
||||
defer tracing.EndSpan(finalizeSpan)
|
||||
|
||||
stateSyncData := []*types.StateSyncData{}
|
||||
|
||||
headerNumber := header.Number.Uint64()
|
||||
|
||||
if IsSprintStart(headerNumber, c.config.Sprint) {
|
||||
ctx := context.Background()
|
||||
var err error
|
||||
|
||||
if IsSprintStart(headerNumber, c.config.Sprint) {
|
||||
cx := statefull.ChainContext{Chain: chain, Bor: c}
|
||||
|
||||
// check and commit span
|
||||
err := c.checkAndCommitSpan(ctx, state, header, cx)
|
||||
tracing.Exec(finalizeCtx, "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
|
||||
// check and commit span
|
||||
err = c.checkAndCommitSpan(finalizeCtx, state, header, cx)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("Error while committing span", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.HeimdallClient != nil {
|
||||
// commit states
|
||||
stateSyncData, err = c.CommitStates(ctx, state, header, cx)
|
||||
tracing.Exec(finalizeCtx, "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
|
||||
// commit states
|
||||
stateSyncData, err = c.CommitStates(finalizeCtx, state, header, cx)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("Error while committing states", "error", err)
|
||||
return nil, err
|
||||
|
|
@ -831,13 +843,21 @@ func (c *Bor) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *typ
|
|||
}
|
||||
}
|
||||
|
||||
if err := c.changeContractCodeIfNeeded(headerNumber, state); err != nil {
|
||||
tracing.Exec(finalizeCtx, "bor.changeContractCodeIfNeeded", func(ctx context.Context, span trace.Span) {
|
||||
err = c.changeContractCodeIfNeeded(headerNumber, state)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("Error changing contract code", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// No block rewards in PoA, so the state remains as is and uncles are dropped
|
||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||
// No block rewards in PoA, so the state remains as it is
|
||||
tracing.Exec(finalizeCtx, "bor.IntermediateRoot", func(ctx context.Context, span trace.Span) {
|
||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||
})
|
||||
|
||||
// Uncles are dropped
|
||||
header.UncleHash = types.CalcUncleHash(nil)
|
||||
|
||||
// Assemble block
|
||||
|
|
@ -847,6 +867,14 @@ func (c *Bor) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *typ
|
|||
bc := chain.(core.BorStateSyncer)
|
||||
bc.SetStateSync(stateSyncData)
|
||||
|
||||
tracing.SetAttributes(
|
||||
finalizeSpan,
|
||||
attribute.Int("number", int(header.Number.Int64())),
|
||||
attribute.String("hash", header.Hash().String()),
|
||||
attribute.Int("number of txs", len(txs)),
|
||||
attribute.Int("gas used", int(block.GasUsed())),
|
||||
)
|
||||
|
||||
// return the final block for sealing
|
||||
return block, nil
|
||||
}
|
||||
|
|
@ -862,7 +890,18 @@ func (c *Bor) Authorize(currentSigner common.Address, signFn SignerFn) {
|
|||
|
||||
// Seal implements consensus.Engine, attempting to create a sealed block using
|
||||
// the local signing credentials.
|
||||
func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
_, sealSpan := tracing.StartSpan(ctx, "bor.Seal")
|
||||
|
||||
var endSpan bool = true
|
||||
|
||||
defer func() {
|
||||
// Only end span in case of early-returns/errors
|
||||
if endSpan {
|
||||
tracing.EndSpan(sealSpan)
|
||||
}
|
||||
}()
|
||||
|
||||
header := block.Header()
|
||||
// Sealing the genesis block is not supported
|
||||
number := header.Number.Uint64()
|
||||
|
|
@ -908,7 +947,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result
|
|||
// Wait until sealing is terminated or delay timeout.
|
||||
log.Info("Waiting for slot to sign and propagate", "number", number, "hash", header.Hash, "delay-in-sec", uint(delay), "delay", common.PrettyDuration(delay))
|
||||
|
||||
go func() {
|
||||
go func(sealSpan trace.Span) {
|
||||
select {
|
||||
case <-stop:
|
||||
log.Debug("Discarding sealing operation for block", "number", number)
|
||||
|
|
@ -931,13 +970,27 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result
|
|||
"delay", delay,
|
||||
"headerDifficulty", header.Difficulty,
|
||||
)
|
||||
|
||||
tracing.SetAttributes(
|
||||
sealSpan,
|
||||
attribute.Int("number", int(number)),
|
||||
attribute.String("hash", header.Hash().String()),
|
||||
attribute.Int("delay", int(delay.Milliseconds())),
|
||||
attribute.Int("wiggle", int(wiggle.Milliseconds())),
|
||||
attribute.Bool("out-of-turn", wiggle > 0),
|
||||
)
|
||||
|
||||
tracing.EndSpan(sealSpan)
|
||||
}
|
||||
select {
|
||||
case results <- block.WithSeal(header):
|
||||
default:
|
||||
log.Warn("Sealing result was not read by miner", "number", number, "sealhash", SealHash(header, c.config))
|
||||
}
|
||||
}()
|
||||
}(sealSpan)
|
||||
|
||||
// Set the endSpan flag to false, as the go routine will handle it
|
||||
endSpan = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1000,13 +1053,13 @@ func (c *Bor) checkAndCommitSpan(
|
|||
) error {
|
||||
headerNumber := header.Number.Uint64()
|
||||
|
||||
currentSpan, err := c.spanner.GetCurrentSpan(ctx, header.ParentHash)
|
||||
span, err := c.spanner.GetCurrentSpan(ctx, header.ParentHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.needToCommitSpan(currentSpan, headerNumber) {
|
||||
return c.FetchAndCommitSpan(ctx, currentSpan.ID+1, state, header, chain)
|
||||
if c.needToCommitSpan(span, headerNumber) {
|
||||
return c.FetchAndCommitSpan(ctx, span.ID+1, state, header, chain)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -1076,6 +1129,7 @@ func (c *Bor) CommitStates(
|
|||
header *types.Header,
|
||||
chain statefull.ChainContext,
|
||||
) ([]*types.StateSyncData, error) {
|
||||
fetchStart := time.Now()
|
||||
number := header.Number.Uint64()
|
||||
|
||||
_lastStateID, err := c.GenesisContractsClient.LastStateId(number - 1)
|
||||
|
|
@ -1102,6 +1156,8 @@ func (c *Bor) CommitStates(
|
|||
}
|
||||
}
|
||||
|
||||
fetchTime := time.Since(fetchStart)
|
||||
processStart := time.Now()
|
||||
totalGas := 0 /// limit on gas for state sync per block
|
||||
chainID := c.chainConfig.ChainID.String()
|
||||
stateSyncs := make([]*types.StateSyncData, len(eventRecords))
|
||||
|
|
@ -1140,7 +1196,9 @@ func (c *Bor) CommitStates(
|
|||
lastStateID++
|
||||
}
|
||||
|
||||
log.Info("StateSyncData", "Gas", totalGas, "Block-number", number, "LastStateID", lastStateID, "TotalRecords", len(eventRecords))
|
||||
processTime := time.Since(processStart)
|
||||
|
||||
log.Info("StateSyncData", "gas", totalGas, "number", number, "lastStateID", lastStateID, "total records", len(eventRecords), "fetch time", int(fetchTime.Milliseconds()), "process time", int(processTime.Milliseconds()))
|
||||
|
||||
return stateSyncs, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
package bor
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/bor/valset"
|
||||
)
|
||||
|
||||
//go:generate mockgen -destination=./validators_getter_mock.go -package=bor . ValidatorsGetter
|
||||
type ValidatorsGetter interface {
|
||||
GetCurrentValidators(headerHash common.Hash, blockNumber uint64) ([]*valset.Validator, error)
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/ethereum/go-ethereum/consensus/bor (interfaces: ValidatorsGetter)
|
||||
|
||||
// Package bor is a generated GoMock package.
|
||||
package bor
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
common "github.com/ethereum/go-ethereum/common"
|
||||
valset "github.com/ethereum/go-ethereum/consensus/bor/valset"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockValidatorsGetter is a mock of ValidatorsGetter interface.
|
||||
type MockValidatorsGetter struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockValidatorsGetterMockRecorder
|
||||
}
|
||||
|
||||
// MockValidatorsGetterMockRecorder is the mock recorder for MockValidatorsGetter.
|
||||
type MockValidatorsGetterMockRecorder struct {
|
||||
mock *MockValidatorsGetter
|
||||
}
|
||||
|
||||
// NewMockValidatorsGetter creates a new mock instance.
|
||||
func NewMockValidatorsGetter(ctrl *gomock.Controller) *MockValidatorsGetter {
|
||||
mock := &MockValidatorsGetter{ctrl: ctrl}
|
||||
mock.recorder = &MockValidatorsGetterMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockValidatorsGetter) EXPECT() *MockValidatorsGetterMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetCurrentValidators mocks base method.
|
||||
func (m *MockValidatorsGetter) GetCurrentValidators(arg0 common.Hash, arg1 uint64) ([]*valset.Validator, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetCurrentValidators", arg0, arg1)
|
||||
ret0, _ := ret[0].([]*valset.Validator)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetCurrentValidators indicates an expected call of GetCurrentValidators.
|
||||
func (mr *MockValidatorsGetterMockRecorder) GetCurrentValidators(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidators", reflect.TypeOf((*MockValidatorsGetter)(nil).GetCurrentValidators), arg0, arg1)
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ package clique
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -569,7 +570,7 @@ func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
|
|||
|
||||
// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
|
||||
// nor block rewards given, and returns the final block.
|
||||
func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
func (c *Clique) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
// Finalize block
|
||||
c.Finalize(chain, header, state, txs, uncles)
|
||||
|
||||
|
|
@ -589,7 +590,7 @@ func (c *Clique) Authorize(signer common.Address, signFn SignerFn) {
|
|||
|
||||
// Seal implements consensus.Engine, attempting to create a sealed block using
|
||||
// the local signing credentials.
|
||||
func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
func (c *Clique) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
header := block.Header()
|
||||
|
||||
// Sealing the genesis block is not supported
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package consensus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -97,7 +98,7 @@ type Engine interface {
|
|||
//
|
||||
// Note: The block header and state database might be updated to reflect any
|
||||
// consensus rules that happen at finalization (e.g. block rewards).
|
||||
FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
|
||||
FinalizeAndAssemble(ctx context.Context, chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
|
||||
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)
|
||||
|
||||
// Seal generates a new sealing request for the given input block and pushes
|
||||
|
|
@ -105,7 +106,7 @@ type Engine interface {
|
|||
//
|
||||
// Note, the method returns immediately and will send the result async. More
|
||||
// than one result may also be returned depending on the consensus algorithm.
|
||||
Seal(chain ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error
|
||||
Seal(ctx context.Context, chain ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error
|
||||
|
||||
// SealHash returns the hash of a block prior to it being sealed.
|
||||
SealHash(header *types.Header) common.Hash
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package ethash
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
|
@ -598,7 +599,7 @@ func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.
|
|||
|
||||
// FinalizeAndAssemble implements consensus.Engine, accumulating the block and
|
||||
// uncle rewards, setting the final state and assembling the block.
|
||||
func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
func (ethash *Ethash) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||
// Finalize block
|
||||
ethash.Finalize(chain, header, state, txs, uncles)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package ethash
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
|
|
@ -38,7 +39,7 @@ func TestTestMode(t *testing.T) {
|
|||
defer ethash.Close()
|
||||
|
||||
results := make(chan *types.Block)
|
||||
err := ethash.Seal(nil, types.NewBlockWithHeader(header), results, nil)
|
||||
err := ethash.Seal(context.Background(), nil, types.NewBlockWithHeader(header), results, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to seal block: %v", err)
|
||||
}
|
||||
|
|
@ -111,12 +112,13 @@ func TestRemoteSealer(t *testing.T) {
|
|||
|
||||
// Push new work.
|
||||
results := make(chan *types.Block)
|
||||
ethash.Seal(nil, block, results, nil)
|
||||
err := ethash.Seal(context.Background(), nil, block, results, nil)
|
||||
|
||||
var (
|
||||
work [4]string
|
||||
err error
|
||||
)
|
||||
if err != nil {
|
||||
t.Error("error in sealing block")
|
||||
}
|
||||
|
||||
var work [4]string
|
||||
if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() {
|
||||
t.Error("expect to return a mining work has same hash")
|
||||
}
|
||||
|
|
@ -128,7 +130,11 @@ func TestRemoteSealer(t *testing.T) {
|
|||
header = &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(1000)}
|
||||
block = types.NewBlockWithHeader(header)
|
||||
sealhash = ethash.SealHash(header)
|
||||
ethash.Seal(nil, block, results, nil)
|
||||
err = ethash.Seal(context.Background(), nil, block, results, nil)
|
||||
|
||||
if err != nil {
|
||||
t.Error("error in sealing block")
|
||||
}
|
||||
|
||||
if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() {
|
||||
t.Error("expect to return the latest pushed work")
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ var (
|
|||
|
||||
// Seal implements consensus.Engine, attempting to find a nonce that satisfies
|
||||
// the block's difficulty requirements.
|
||||
func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
func (ethash *Ethash) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
||||
// If we're running a fake PoW, simply return a 0 nonce immediately
|
||||
if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake {
|
||||
header := block.Header()
|
||||
|
|
@ -62,7 +62,7 @@ func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block
|
|||
}
|
||||
// If we're running a shared PoW, delegate sealing to it
|
||||
if ethash.shared != nil {
|
||||
return ethash.shared.Seal(chain, block, results, stop)
|
||||
return ethash.shared.Seal(ctx, chain, block, results, stop)
|
||||
}
|
||||
// Create a runner and the multiple search threads it directs
|
||||
abort := make(chan struct{})
|
||||
|
|
@ -117,7 +117,8 @@ func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block
|
|||
case <-ethash.update:
|
||||
// Thread count was changed on user request, restart
|
||||
close(abort)
|
||||
if err := ethash.Seal(chain, block, results, stop); err != nil {
|
||||
|
||||
if err := ethash.Seal(ctx, chain, block, results, stop); err != nil {
|
||||
ethash.config.Log.Error("Failed to restart sealing after update", "err", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package ethash
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
|
|
@ -57,7 +58,11 @@ func TestRemoteNotify(t *testing.T) {
|
|||
header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)}
|
||||
block := types.NewBlockWithHeader(header)
|
||||
|
||||
ethash.Seal(nil, block, nil, nil)
|
||||
err := ethash.Seal(context.Background(), nil, block, nil, nil)
|
||||
|
||||
if err != nil {
|
||||
t.Error("error in sealing block")
|
||||
}
|
||||
select {
|
||||
case work := <-sink:
|
||||
if want := ethash.SealHash(header).Hex(); work[0] != want {
|
||||
|
|
@ -105,7 +110,11 @@ func TestRemoteNotifyFull(t *testing.T) {
|
|||
header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)}
|
||||
block := types.NewBlockWithHeader(header)
|
||||
|
||||
ethash.Seal(nil, block, nil, nil)
|
||||
err := ethash.Seal(context.Background(), nil, block, nil, nil)
|
||||
|
||||
if err != nil {
|
||||
t.Error("error in sealing block")
|
||||
}
|
||||
select {
|
||||
case work := <-sink:
|
||||
if want := "0x" + strconv.FormatUint(header.Number.Uint64(), 16); work["number"] != want {
|
||||
|
|
@ -151,7 +160,11 @@ func TestRemoteMultiNotify(t *testing.T) {
|
|||
for i := 0; i < cap(sink); i++ {
|
||||
header := &types.Header{Number: big.NewInt(int64(i)), Difficulty: big.NewInt(100)}
|
||||
block := types.NewBlockWithHeader(header)
|
||||
ethash.Seal(nil, block, results, nil)
|
||||
err := ethash.Seal(context.Background(), nil, block, results, nil)
|
||||
|
||||
if err != nil {
|
||||
t.Error("error in sealing block")
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < cap(sink); i++ {
|
||||
|
|
@ -204,7 +217,11 @@ func TestRemoteMultiNotifyFull(t *testing.T) {
|
|||
for i := 0; i < cap(sink); i++ {
|
||||
header := &types.Header{Number: big.NewInt(int64(i)), Difficulty: big.NewInt(100)}
|
||||
block := types.NewBlockWithHeader(header)
|
||||
ethash.Seal(nil, block, results, nil)
|
||||
err := ethash.Seal(context.Background(), nil, block, results, nil)
|
||||
|
||||
if err != nil {
|
||||
t.Error("error in sealing block")
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < cap(sink); i++ {
|
||||
|
|
@ -270,7 +287,11 @@ func TestStaleSubmission(t *testing.T) {
|
|||
|
||||
for id, c := range testcases {
|
||||
for _, h := range c.headers {
|
||||
ethash.Seal(nil, types.NewBlockWithHeader(h), results, nil)
|
||||
err := ethash.Seal(context.Background(), nil, types.NewBlockWithHeader(h), results, nil)
|
||||
|
||||
if err != nil {
|
||||
t.Error("error in sealing block")
|
||||
}
|
||||
}
|
||||
if res := api.SubmitWork(fakeNonce, ethash.SealHash(c.headers[c.submitIndex]), fakeDigest); res != c.submitRes {
|
||||
t.Errorf("case %d submit result mismatch, want %t, get %t", id+1, c.submitRes, res)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
|
|||
|
||||
// genUncles generates blocks with two uncle headers.
|
||||
func genUncles(i int, gen *BlockGen) {
|
||||
if i >= 6 {
|
||||
if i >= 7 {
|
||||
b2 := gen.PrevBlock(i - 6).Header()
|
||||
b2.Extra = []byte("foo")
|
||||
gen.AddUncle(b2)
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ type BlockChain struct {
|
|||
// NewBlockChain returns a fully initialised block chain using information
|
||||
// available in the database. It initialises the default Ethereum Validator
|
||||
// and Processor.
|
||||
//
|
||||
//nolint:gocognit
|
||||
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64, checker ethereum.ChainValidator) (*BlockChain, error) {
|
||||
if cacheConfig == nil {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
|
|
@ -258,7 +259,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
}
|
||||
if b.engine != nil {
|
||||
// Finalize and seal the block
|
||||
block, _ := b.engine.FinalizeAndAssemble(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts)
|
||||
block, _ := b.engine.FinalizeAndAssemble(context.Background(), chainreader, b.header, statedb, b.txs, b.uncles, b.receipts)
|
||||
|
||||
// Write state changes to db
|
||||
root, err := statedb.Commit(config.IsEIP158(b.header.Number))
|
||||
|
|
|
|||
|
|
@ -508,6 +508,10 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa
|
|||
// Initialize a price and received time based heap with the head transactions
|
||||
heads := make(TxByPriceAndTime, 0, len(txs))
|
||||
for from, accTxs := range txs {
|
||||
if len(accTxs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
acc, _ := Sender(signer, accTxs[0])
|
||||
wrapped, err := NewTxWithMinerFee(accTxs[0], baseFee)
|
||||
// Remove transaction if sender doesn't match from, or if wrapping fails.
|
||||
|
|
@ -550,6 +554,10 @@ func (t *TransactionsByPriceAndNonce) Shift() {
|
|||
heap.Pop(&t.heads)
|
||||
}
|
||||
|
||||
func (t *TransactionsByPriceAndNonce) GetTxs() int {
|
||||
return len(t.txs)
|
||||
}
|
||||
|
||||
// Pop removes the best transaction, *not* replacing it with the next one from
|
||||
// the same account. This should be used when a transaction cannot be executed
|
||||
// and hence all subsequent ones should be discarded from the same account.
|
||||
|
|
|
|||
|
|
@ -4,4 +4,6 @@ The ```bor removedb``` command will remove the blockchain and state databases at
|
|||
|
||||
## Options
|
||||
|
||||
- ```datadir```: Path of the data directory to store information
|
||||
- ```address```: Address of the grpc endpoint
|
||||
|
||||
- ```datadir```: Path of the data directory to store information
|
||||
|
|
@ -16,18 +16,22 @@ The ```bor server``` command runs the Bor client.
|
|||
|
||||
- ```config```: File for the config file
|
||||
|
||||
- ```syncmode```: Blockchain sync mode ("fast", "full", or "snap")
|
||||
- ```syncmode```: Blockchain sync mode (only "full" sync supported)
|
||||
|
||||
- ```gcmode```: Blockchain garbage collection mode ("full", "archive")
|
||||
|
||||
- ```requiredblocks```: Comma separated block number-to-hash mappings to enforce (<number>=<hash>)
|
||||
- ```eth.requiredblocks```: Comma separated block number-to-hash mappings to require for peering (<number>=<hash>)
|
||||
|
||||
- ```snapshot```: Disables/Enables the snapshot-database mode (default = true)
|
||||
- ```snapshot```: Enables the snapshot-database mode (default = true)
|
||||
|
||||
- ```bor.logs```: Enables bor log retrieval (default = false)
|
||||
|
||||
- ```bor.heimdall```: URL of Heimdall service
|
||||
|
||||
- ```bor.withoutheimdall```: Run without Heimdall service (for testing purpose)
|
||||
|
||||
- ```bor.heimdallgRPC```: Address of Heimdall gRPC service
|
||||
|
||||
- ```ethstats```: Reporting URL of a ethstats service (nodename:secret@host:port)
|
||||
|
||||
- ```gpo.blocks```: Number of recent blocks to check for gas prices
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -122,7 +122,7 @@ require (
|
|||
github.com/mitchellh/pointerstructure v1.2.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/posener/complete v1.1.1 // indirect
|
||||
|
|
@ -130,7 +130,7 @@ require (
|
|||
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.2.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.2.0
|
||||
go.opentelemetry.io/proto/otlp v0.10.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
|
|
|
|||
|
|
@ -62,9 +62,12 @@ type Config struct {
|
|||
// GcMode selects the garbage collection mode for the trie
|
||||
GcMode string `hcl:"gcmode,optional" toml:"gcmode,optional"`
|
||||
|
||||
// Snapshot disables/enables the snapshot database mode
|
||||
// Snapshot enables the snapshot database mode
|
||||
Snapshot bool `hcl:"snapshot,optional" toml:"snapshot,optional"`
|
||||
|
||||
// BorLogs enables bor log retrieval
|
||||
BorLogs bool `hcl:"bor.logs,optional" toml:"bor.logs,optional"`
|
||||
|
||||
// Ethstats is the address of the ethstats server to send telemetry
|
||||
Ethstats string `hcl:"ethstats,optional" toml:"ethstats,optional"`
|
||||
|
||||
|
|
@ -420,6 +423,7 @@ func DefaultConfig() *Config {
|
|||
SyncMode: "full",
|
||||
GcMode: "full",
|
||||
Snapshot: true,
|
||||
BorLogs: false,
|
||||
TxPool: &TxPoolConfig{
|
||||
Locals: []string{},
|
||||
NoLocals: false,
|
||||
|
|
@ -649,6 +653,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
|
|||
n.NetworkId = c.chain.NetworkId
|
||||
n.Genesis = c.chain.Genesis
|
||||
}
|
||||
|
||||
n.HeimdallURL = c.Heimdall.URL
|
||||
n.WithoutHeimdall = c.Heimdall.Without
|
||||
n.HeimdallgRPCAddress = c.Heimdall.GRPCAddress
|
||||
|
|
@ -881,6 +886,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
|
|||
}
|
||||
}
|
||||
|
||||
n.BorLogs = c.BorLogs
|
||||
n.DatabaseHandles = dbHandles
|
||||
|
||||
return &n, nil
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func (c *Command) Flags() *flagset.Flagset {
|
|||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "syncmode",
|
||||
Usage: `Blockchain sync mode ("fast", "full", or "snap")`,
|
||||
Usage: `Blockchain sync mode (only "full" sync supported)`,
|
||||
Value: &c.cliConfig.SyncMode,
|
||||
Default: c.cliConfig.SyncMode,
|
||||
})
|
||||
|
|
@ -62,10 +62,16 @@ func (c *Command) Flags() *flagset.Flagset {
|
|||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "snapshot",
|
||||
Usage: `Disables/Enables the snapshot-database mode (default = true)`,
|
||||
Usage: `Enables the snapshot-database mode (default = true)`,
|
||||
Value: &c.cliConfig.Snapshot,
|
||||
Default: c.cliConfig.Snapshot,
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "bor.logs",
|
||||
Usage: `Enables bor log retrieval (default = false)`,
|
||||
Value: &c.cliConfig.BorLogs,
|
||||
Default: c.cliConfig.BorLogs,
|
||||
})
|
||||
|
||||
// heimdall
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
|
|
|
|||
303
miner/worker.go
303
miner/worker.go
|
|
@ -17,6 +17,7 @@
|
|||
package miner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
|
@ -25,8 +26,12 @@ import (
|
|||
"time"
|
||||
|
||||
mapset "github.com/deckarep/golang-set"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/tracing"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
|
|
@ -144,6 +149,8 @@ func (env *environment) discard() {
|
|||
|
||||
// task contains all information for consensus engine sealing and result submitting.
|
||||
type task struct {
|
||||
//nolint:containedctx
|
||||
ctx context.Context
|
||||
receipts []*types.Receipt
|
||||
state *state.StateDB
|
||||
block *types.Block
|
||||
|
|
@ -158,6 +165,8 @@ const (
|
|||
|
||||
// newWorkReq represents a request for new sealing work submitting with relative interrupt notifier.
|
||||
type newWorkReq struct {
|
||||
//nolint:containedctx
|
||||
ctx context.Context
|
||||
interrupt *int32
|
||||
noempty bool
|
||||
timestamp int64
|
||||
|
|
@ -165,6 +174,8 @@ type newWorkReq struct {
|
|||
|
||||
// getWorkReq represents a request for getting a new sealing work with provided parameters.
|
||||
type getWorkReq struct {
|
||||
//nolint:containedctx
|
||||
ctx context.Context
|
||||
params *generateParams
|
||||
err error
|
||||
result chan *types.Block
|
||||
|
|
@ -287,9 +298,12 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
|
|||
recommit = minRecommitInterval
|
||||
}
|
||||
|
||||
ctx := tracing.WithTracer(context.Background(), otel.GetTracerProvider().Tracer("MinerWorker"))
|
||||
|
||||
worker.wg.Add(4)
|
||||
go worker.mainLoop()
|
||||
go worker.newWorkLoop(recommit)
|
||||
|
||||
go worker.mainLoop(ctx)
|
||||
go worker.newWorkLoop(ctx, recommit)
|
||||
go worker.resultLoop()
|
||||
go worker.taskLoop()
|
||||
|
||||
|
|
@ -419,7 +433,9 @@ func recalcRecommit(minRecommit, prev time.Duration, target float64, inc bool) t
|
|||
}
|
||||
|
||||
// newWorkLoop is a standalone goroutine to submit new sealing work upon received events.
|
||||
func (w *worker) newWorkLoop(recommit time.Duration) {
|
||||
//
|
||||
//nolint:gocognit
|
||||
func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) {
|
||||
defer w.wg.Done()
|
||||
var (
|
||||
interrupt *int32
|
||||
|
|
@ -433,12 +449,16 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||
|
||||
// commit aborts in-flight transaction execution with given signal and resubmits a new one.
|
||||
commit := func(noempty bool, s int32) {
|
||||
// we close spans only by the place we created them
|
||||
ctx, span := tracing.Trace(ctx, "worker.newWorkLoop.commit")
|
||||
tracing.EndSpan(span)
|
||||
|
||||
if interrupt != nil {
|
||||
atomic.StoreInt32(interrupt, s)
|
||||
}
|
||||
interrupt = new(int32)
|
||||
select {
|
||||
case w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty, timestamp: timestamp}:
|
||||
case w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty, timestamp: timestamp, ctx: ctx}:
|
||||
case <-w.exitCh:
|
||||
return
|
||||
}
|
||||
|
|
@ -447,6 +467,9 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||
}
|
||||
// clearPending cleans the stale pending tasks.
|
||||
clearPending := func(number uint64) {
|
||||
_, span := tracing.Trace(ctx, "worker.newWorkLoop.clearPending")
|
||||
tracing.EndSpan(span)
|
||||
|
||||
w.pendingMu.Lock()
|
||||
for h, t := range w.pendingTasks {
|
||||
if t.block.NumberU64()+staleThreshold <= number {
|
||||
|
|
@ -519,7 +542,8 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||
// mainLoop is responsible for generating and submitting sealing work based on
|
||||
// the received event. It can support two modes: automatically generate task and
|
||||
// submit it or return task according to given parameters for various proposes.
|
||||
func (w *worker) mainLoop() {
|
||||
// nolint: gocognit
|
||||
func (w *worker) mainLoop(ctx context.Context) {
|
||||
defer w.wg.Done()
|
||||
defer w.txsSub.Unsubscribe()
|
||||
defer w.chainHeadSub.Unsubscribe()
|
||||
|
|
@ -536,10 +560,10 @@ func (w *worker) mainLoop() {
|
|||
for {
|
||||
select {
|
||||
case req := <-w.newWorkCh:
|
||||
w.commitWork(req.interrupt, req.noempty, req.timestamp)
|
||||
w.commitWork(req.ctx, req.interrupt, req.noempty, req.timestamp)
|
||||
|
||||
case req := <-w.getWorkCh:
|
||||
block, err := w.generateWork(req.params)
|
||||
block, err := w.generateWork(req.ctx, req.params)
|
||||
if err != nil {
|
||||
req.err = err
|
||||
req.result <- nil
|
||||
|
|
@ -567,7 +591,10 @@ func (w *worker) mainLoop() {
|
|||
if w.isRunning() && w.current != nil && len(w.current.uncles) < 2 {
|
||||
start := time.Now()
|
||||
if err := w.commitUncle(w.current, ev.Block.Header()); err == nil {
|
||||
w.commit(w.current.copy(), nil, true, start)
|
||||
commitErr := w.commit(ctx, w.current.copy(), nil, true, start)
|
||||
if commitErr != nil {
|
||||
log.Error("error while committing work for mining", "err", commitErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -614,7 +641,7 @@ func (w *worker) mainLoop() {
|
|||
// submit sealing work here since all empty submission will be rejected
|
||||
// by clique. Of course the advance sealing(empty submission) is disabled.
|
||||
if w.chainConfig.Clique != nil && w.chainConfig.Clique.Period == 0 {
|
||||
w.commitWork(nil, true, time.Now().Unix())
|
||||
w.commitWork(ctx, nil, true, time.Now().Unix())
|
||||
}
|
||||
}
|
||||
atomic.AddInt32(&w.newTxs, int32(len(ev.Txs)))
|
||||
|
|
@ -670,7 +697,7 @@ func (w *worker) taskLoop() {
|
|||
w.pendingTasks[sealHash] = task
|
||||
w.pendingMu.Unlock()
|
||||
|
||||
if err := w.engine.Seal(w.chain, task.block, w.resultCh, stopCh); err != nil {
|
||||
if err := w.engine.Seal(task.ctx, w.chain, task.block, w.resultCh, stopCh); err != nil {
|
||||
log.Warn("Block sealing failed", "err", err)
|
||||
w.pendingMu.Lock()
|
||||
delete(w.pendingTasks, sealHash)
|
||||
|
|
@ -694,10 +721,12 @@ func (w *worker) resultLoop() {
|
|||
if block == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Short circuit when receiving duplicate result caused by resubmitting.
|
||||
if w.chain.HasBlock(block.Hash(), block.NumberU64()) {
|
||||
continue
|
||||
}
|
||||
|
||||
oldBlock := w.chain.GetBlockByNumber(block.NumberU64())
|
||||
if oldBlock != nil {
|
||||
oldBlockAuthor, _ := w.chain.Engine().Author(oldBlock.Header())
|
||||
|
|
@ -707,49 +736,72 @@ func (w *worker) resultLoop() {
|
|||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
sealhash = w.engine.SealHash(block.Header())
|
||||
hash = block.Hash()
|
||||
)
|
||||
|
||||
w.pendingMu.RLock()
|
||||
task, exist := w.pendingTasks[sealhash]
|
||||
w.pendingMu.RUnlock()
|
||||
|
||||
if !exist {
|
||||
log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", hash)
|
||||
continue
|
||||
}
|
||||
|
||||
// Different block could share same sealhash, deep copy here to prevent write-write conflict.
|
||||
var (
|
||||
receipts = make([]*types.Receipt, len(task.receipts))
|
||||
logs []*types.Log
|
||||
err error
|
||||
)
|
||||
for i, taskReceipt := range task.receipts {
|
||||
receipt := new(types.Receipt)
|
||||
receipts[i] = receipt
|
||||
*receipt = *taskReceipt
|
||||
|
||||
// add block location fields
|
||||
receipt.BlockHash = hash
|
||||
receipt.BlockNumber = block.Number()
|
||||
receipt.TransactionIndex = uint(i)
|
||||
tracing.Exec(task.ctx, "resultLoop", func(ctx context.Context, span trace.Span) {
|
||||
for i, taskReceipt := range task.receipts {
|
||||
receipt := new(types.Receipt)
|
||||
receipts[i] = receipt
|
||||
*receipt = *taskReceipt
|
||||
|
||||
// Update the block hash in all logs since it is now available and not when the
|
||||
// receipt/log of individual transactions were created.
|
||||
receipt.Logs = make([]*types.Log, len(taskReceipt.Logs))
|
||||
for i, taskLog := range taskReceipt.Logs {
|
||||
log := new(types.Log)
|
||||
receipt.Logs[i] = log
|
||||
*log = *taskLog
|
||||
log.BlockHash = hash
|
||||
// add block location fields
|
||||
receipt.BlockHash = hash
|
||||
receipt.BlockNumber = block.Number()
|
||||
receipt.TransactionIndex = uint(i)
|
||||
|
||||
// Update the block hash in all logs since it is now available and not when the
|
||||
// receipt/log of individual transactions were created.
|
||||
receipt.Logs = make([]*types.Log, len(taskReceipt.Logs))
|
||||
for i, taskLog := range taskReceipt.Logs {
|
||||
log := new(types.Log)
|
||||
receipt.Logs[i] = log
|
||||
*log = *taskLog
|
||||
log.BlockHash = hash
|
||||
}
|
||||
logs = append(logs, receipt.Logs...)
|
||||
}
|
||||
logs = append(logs, receipt.Logs...)
|
||||
}
|
||||
// Commit block and state to database.
|
||||
_, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true)
|
||||
|
||||
// Commit block and state to database.
|
||||
tracing.ElapsedTime(ctx, span, "WriteBlockAndSetHead time taken", func(_ context.Context, _ trace.Span) {
|
||||
_, err = w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true)
|
||||
})
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
attribute.String("hash", hash.String()),
|
||||
attribute.Int("number", int(block.Number().Uint64())),
|
||||
attribute.Int("txns", block.Transactions().Len()),
|
||||
attribute.Int("gas used", int(block.GasUsed())),
|
||||
attribute.Int("elapsed", int(time.Since(task.createdAt).Milliseconds())),
|
||||
attribute.Bool("error", err != nil),
|
||||
)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("Failed writing block to chain", "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash,
|
||||
"elapsed", common.PrettyDuration(time.Since(task.createdAt)))
|
||||
|
||||
|
|
@ -758,7 +810,6 @@ func (w *worker) resultLoop() {
|
|||
|
||||
// Insert the block into the set of pending ones to resultLoop for confirmations
|
||||
w.unconfirmed.Insert(block.NumberU64(), block.Hash())
|
||||
|
||||
case <-w.exitCh:
|
||||
return
|
||||
}
|
||||
|
|
@ -1069,78 +1120,176 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
|
|||
// fillTransactions retrieves the pending transactions from the txpool and fills them
|
||||
// into the given sealing block. The transaction selection and ordering strategy can
|
||||
// be customized with the plugin in the future.
|
||||
func (w *worker) fillTransactions(interrupt *int32, env *environment) {
|
||||
func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) {
|
||||
ctx, span := tracing.StartSpan(ctx, "fillTransactions")
|
||||
defer tracing.EndSpan(span)
|
||||
|
||||
// Split the pending transactions into locals and remotes
|
||||
// Fill the block with all available pending transactions.
|
||||
pending := w.eth.TxPool().Pending(true)
|
||||
localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending
|
||||
for _, account := range w.eth.TxPool().Locals() {
|
||||
if txs := remoteTxs[account]; len(txs) > 0 {
|
||||
delete(remoteTxs, account)
|
||||
localTxs[account] = txs
|
||||
|
||||
var (
|
||||
localTxsCount int
|
||||
remoteTxsCount int
|
||||
localTxs = make(map[common.Address]types.Transactions)
|
||||
remoteTxs map[common.Address]types.Transactions
|
||||
)
|
||||
|
||||
tracing.Exec(ctx, "worker.SplittingTransactions", func(ctx context.Context, span trace.Span) {
|
||||
pending := w.eth.TxPool().Pending(true)
|
||||
remoteTxs = pending
|
||||
|
||||
for _, account := range w.eth.TxPool().Locals() {
|
||||
if txs := remoteTxs[account]; len(txs) > 0 {
|
||||
delete(remoteTxs, account)
|
||||
localTxs[account] = txs
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(localTxs) > 0 {
|
||||
txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
|
||||
if w.commitTransactions(env, txs, interrupt) {
|
||||
|
||||
localTxsCount = len(localTxs)
|
||||
remoteTxsCount = len(remoteTxs)
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
attribute.Int("len of local txs", localTxsCount),
|
||||
attribute.Int("len of remote txs", remoteTxsCount),
|
||||
)
|
||||
})
|
||||
|
||||
var (
|
||||
localEnvTCount int
|
||||
remoteEnvTCount int
|
||||
committed bool
|
||||
)
|
||||
|
||||
if localTxsCount > 0 {
|
||||
var txs *types.TransactionsByPriceAndNonce
|
||||
|
||||
tracing.Exec(ctx, "worker.LocalTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) {
|
||||
txs = types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
attribute.Int("len of tx local Heads", txs.GetTxs()),
|
||||
)
|
||||
})
|
||||
|
||||
tracing.Exec(ctx, "worker.LocalCommitTransactions", func(ctx context.Context, span trace.Span) {
|
||||
committed = w.commitTransactions(env, txs, interrupt)
|
||||
})
|
||||
|
||||
if committed {
|
||||
return
|
||||
}
|
||||
|
||||
localEnvTCount = env.tcount
|
||||
}
|
||||
if len(remoteTxs) > 0 {
|
||||
txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
|
||||
if w.commitTransactions(env, txs, interrupt) {
|
||||
|
||||
if remoteTxsCount > 0 {
|
||||
var txs *types.TransactionsByPriceAndNonce
|
||||
|
||||
tracing.Exec(ctx, "worker.RemoteTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) {
|
||||
txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
attribute.Int("len of tx remote Heads", txs.GetTxs()),
|
||||
)
|
||||
})
|
||||
|
||||
tracing.Exec(ctx, "worker.RemoteCommitTransactions", func(ctx context.Context, span trace.Span) {
|
||||
committed = w.commitTransactions(env, txs, interrupt)
|
||||
})
|
||||
|
||||
if committed {
|
||||
return
|
||||
}
|
||||
|
||||
remoteEnvTCount = env.tcount
|
||||
}
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
attribute.Int("len of final local txs ", localEnvTCount),
|
||||
attribute.Int("len of final remote txs", remoteEnvTCount),
|
||||
)
|
||||
}
|
||||
|
||||
// generateWork generates a sealing block based on the given parameters.
|
||||
func (w *worker) generateWork(params *generateParams) (*types.Block, error) {
|
||||
func (w *worker) generateWork(ctx context.Context, params *generateParams) (*types.Block, error) {
|
||||
work, err := w.prepareWork(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer work.discard()
|
||||
|
||||
w.fillTransactions(nil, work)
|
||||
return w.engine.FinalizeAndAssemble(w.chain, work.header, work.state, work.txs, work.unclelist(), work.receipts)
|
||||
w.fillTransactions(ctx, nil, work)
|
||||
|
||||
return w.engine.FinalizeAndAssemble(ctx, w.chain, work.header, work.state, work.txs, work.unclelist(), work.receipts)
|
||||
}
|
||||
|
||||
// commitWork generates several new sealing tasks based on the parent block
|
||||
// and submit them to the sealer.
|
||||
func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) {
|
||||
func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, timestamp int64) {
|
||||
start := time.Now()
|
||||
|
||||
// Set the coinbase if the worker is running or it's required
|
||||
var coinbase common.Address
|
||||
if w.isRunning() {
|
||||
if w.coinbase == (common.Address{}) {
|
||||
log.Error("Refusing to mine without etherbase")
|
||||
return
|
||||
var (
|
||||
work *environment
|
||||
err error
|
||||
)
|
||||
|
||||
tracing.Exec(ctx, "worker.prepareWork", func(ctx context.Context, span trace.Span) {
|
||||
// Set the coinbase if the worker is running or it's required
|
||||
var coinbase common.Address
|
||||
if w.isRunning() {
|
||||
if w.coinbase == (common.Address{}) {
|
||||
log.Error("Refusing to mine without etherbase")
|
||||
return
|
||||
}
|
||||
|
||||
coinbase = w.coinbase // Use the preset address as the fee recipient
|
||||
}
|
||||
coinbase = w.coinbase // Use the preset address as the fee recipient
|
||||
}
|
||||
work, err := w.prepareWork(&generateParams{
|
||||
timestamp: uint64(timestamp),
|
||||
coinbase: coinbase,
|
||||
|
||||
work, err = w.prepareWork(&generateParams{
|
||||
timestamp: uint64(timestamp),
|
||||
coinbase: coinbase,
|
||||
})
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctx, span := tracing.StartSpan(ctx, "commitWork")
|
||||
defer tracing.EndSpan(span)
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
attribute.Int("number", int(work.header.Number.Uint64())),
|
||||
)
|
||||
|
||||
// Create an empty block based on temporary copied state for
|
||||
// sealing in advance without waiting block execution finished.
|
||||
if !noempty && atomic.LoadUint32(&w.noempty) == 0 {
|
||||
w.commit(work.copy(), nil, false, start)
|
||||
err = w.commit(ctx, work.copy(), nil, false, start)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Fill pending transactions from the txpool
|
||||
w.fillTransactions(interrupt, work)
|
||||
w.commit(work.copy(), w.fullTaskHook, true, start)
|
||||
w.fillTransactions(ctx, interrupt, work)
|
||||
|
||||
err = w.commit(ctx, work.copy(), w.fullTaskHook, true, start)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Swap out the old work with the new one, terminating any leftover
|
||||
// prefetcher processes in the mean time and starting a new one.
|
||||
if w.current != nil {
|
||||
w.current.discard()
|
||||
}
|
||||
|
||||
w.current = work
|
||||
}
|
||||
|
||||
|
|
@ -1148,22 +1297,38 @@ func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) {
|
|||
// and commits new work if consensus engine is running.
|
||||
// Note the assumption is held that the mutation is allowed to the passed env, do
|
||||
// the deep copy first.
|
||||
func (w *worker) commit(env *environment, interval func(), update bool, start time.Time) error {
|
||||
func (w *worker) commit(ctx context.Context, env *environment, interval func(), update bool, start time.Time) error {
|
||||
if w.isRunning() {
|
||||
ctx, span := tracing.StartSpan(ctx, "commit")
|
||||
defer tracing.EndSpan(span)
|
||||
|
||||
if interval != nil {
|
||||
interval()
|
||||
}
|
||||
|
||||
// Create a local environment copy, avoid the data race with snapshot state.
|
||||
// https://github.com/ethereum/go-ethereum/issues/24299
|
||||
env := env.copy()
|
||||
block, err := w.engine.FinalizeAndAssemble(w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts)
|
||||
|
||||
block, err := w.engine.FinalizeAndAssemble(ctx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts)
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
attribute.Int("number", int(block.Number().Uint64())),
|
||||
attribute.String("hash", block.Hash().String()),
|
||||
attribute.String("sealhash", w.engine.SealHash(block.Header()).String()),
|
||||
attribute.Int("len of env.txs", len(env.txs)),
|
||||
attribute.Bool("error", err != nil),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we're post merge, just ignore
|
||||
if !w.isTTDReached(block.Header()) {
|
||||
select {
|
||||
case w.taskCh <- &task{receipts: env.receipts, state: env.state, block: block, createdAt: time.Now()}:
|
||||
case w.taskCh <- &task{ctx: ctx, receipts: env.receipts, state: env.state, block: block, createdAt: time.Now()}:
|
||||
w.unconfirmed.Shift(block.NumberU64() - 1)
|
||||
log.Info("Commit new sealing work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()),
|
||||
"uncles", len(env.uncles), "txs", env.tcount,
|
||||
|
|
@ -1178,11 +1343,14 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti
|
|||
if update {
|
||||
w.updateSnapshot(env)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getSealingBlock generates the sealing block based on the given parameters.
|
||||
func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase common.Address, random common.Hash) (*types.Block, error) {
|
||||
ctx := tracing.WithTracer(context.Background(), otel.GetTracerProvider().Tracer("getSealingBlock"))
|
||||
|
||||
req := &getWorkReq{
|
||||
params: &generateParams{
|
||||
timestamp: timestamp,
|
||||
|
|
@ -1194,13 +1362,16 @@ func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase
|
|||
noExtra: true,
|
||||
},
|
||||
result: make(chan *types.Block, 1),
|
||||
ctx: ctx,
|
||||
}
|
||||
|
||||
select {
|
||||
case w.getWorkCh <- req:
|
||||
block := <-req.result
|
||||
if block == nil {
|
||||
return nil, req.err
|
||||
}
|
||||
|
||||
return block, nil
|
||||
case <-w.exitCh:
|
||||
return nil, errors.New("miner closed")
|
||||
|
|
|
|||
|
|
@ -109,8 +109,9 @@ var nameTagMap = map[string]string{
|
|||
"gcmode": "gcmode",
|
||||
"eth.requiredblocks": "eth.requiredblocks",
|
||||
"0-snapshot": "snapshot",
|
||||
"\"bor.logs\"": "bor.logs",
|
||||
"url": "bor.heimdall",
|
||||
"bor.without": "bor.withoutheimdall",
|
||||
"\"bor.without\"": "bor.withoutheimdall",
|
||||
"grpc-address": "bor.heimdallgRPC",
|
||||
"locals": "txpool.locals",
|
||||
"nolocals": "txpool.nolocals",
|
||||
|
|
@ -231,6 +232,7 @@ var replacedFlagsMapFlag = map[string]string{
|
|||
|
||||
var currentBoolFlags = []string{
|
||||
"snapshot",
|
||||
"bor.logs",
|
||||
"bor.withoutheimdall",
|
||||
"txpool.nolocals",
|
||||
"mine",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,19 @@
|
|||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
# Instructions:
|
||||
# Execute `./getconfig.sh`, and follow the instructions displayed on the terminal
|
||||
# The `*-config.toml` file will be created in the same directory as start.sh
|
||||
# It is recommended to check the flags generated in config.toml
|
||||
|
||||
# Some checks to make commands OS independent
|
||||
OS="$(uname -s)"
|
||||
MKTEMPOPTION=
|
||||
SEDOPTION= ## Not used as of now (TODO)
|
||||
shopt -s nocasematch; if [[ "$OS" == "darwin"* ]]; then
|
||||
SEDOPTION="''"
|
||||
MKTEMPOPTION="-t"
|
||||
fi
|
||||
|
||||
read -p "* Path to start.sh: " startPath
|
||||
# check if start.sh is present
|
||||
|
|
@ -15,7 +24,7 @@ then
|
|||
fi
|
||||
read -p "* Your validator address (e.g. 0xca67a8D767e45056DC92384b488E9Af654d78DE2), or press Enter to skip if running a sentry node: " ADD
|
||||
|
||||
echo "\nThank you, your inputs are:"
|
||||
printf "\nThank you, your inputs are:\n"
|
||||
echo "Path to start.sh: "$startPath
|
||||
echo "Address: "$ADD
|
||||
|
||||
|
|
@ -26,8 +35,9 @@ if [[ -f $confPath ]]
|
|||
then
|
||||
echo "WARN: config.toml exists, data will be overwritten."
|
||||
fi
|
||||
printf "\n"
|
||||
|
||||
tmpDir="$(mktemp -d -t ./temp-dir-XXXXXXXXXXX || oops "Can't create temporary directory")"
|
||||
tmpDir="$(mktemp -d $MKTEMPOPTION ./temp-dir-XXXXXXXXXXX || oops "Can't create temporary directory")"
|
||||
cleanup() {
|
||||
rm -rf "$tmpDir"
|
||||
}
|
||||
|
|
@ -39,8 +49,11 @@ chmod +x $tmpDir/3305fe263dd4a999d58f96deb064e21bb70123d9.sh
|
|||
$tmpDir/3305fe263dd4a999d58f96deb064e21bb70123d9.sh $ADD
|
||||
rm $tmpDir/3305fe263dd4a999d58f96deb064e21bb70123d9.sh
|
||||
|
||||
|
||||
sed -i '' "s%*%'*'%g" ./temp
|
||||
shopt -s nocasematch; if [[ "$OS" == "darwin"* ]]; then
|
||||
sed -i '' "s%*%'*'%g" ./temp
|
||||
else
|
||||
sed -i "s%*%'*'%g" ./temp
|
||||
fi
|
||||
|
||||
# read the flags from `./temp`
|
||||
dumpconfigflags=$(head -1 ./temp)
|
||||
|
|
@ -51,17 +64,27 @@ bash -c "$command"
|
|||
|
||||
rm ./temp
|
||||
|
||||
printf "\n"
|
||||
|
||||
if [[ -f ./tempStaticNodes.json ]]
|
||||
then
|
||||
echo "JSON StaticNodes found"
|
||||
staticnodesjson=$(head -1 ./tempStaticNodes.json)
|
||||
sed -i '' "s%static-nodes = \[\]%static-nodes = \[\"${staticnodesjson}\"\]%" $confPath
|
||||
shopt -s nocasematch; if [[ "$OS" == "darwin"* ]]; then
|
||||
sed -i '' "s%static-nodes = \[\]%static-nodes = \[\"${staticnodesjson}\"\]%" $confPath
|
||||
else
|
||||
sed -i "s%static-nodes = \[\]%static-nodes = \[\"${staticnodesjson}\"\]%" $confPath
|
||||
fi
|
||||
rm ./tempStaticNodes.json
|
||||
elif [[ -f ./tempStaticNodes.toml ]]
|
||||
then
|
||||
echo "TOML StaticNodes found"
|
||||
staticnodestoml=$(head -1 ./tempStaticNodes.toml)
|
||||
sed -i '' "s%static-nodes = \[\]%static-nodes = \[\"${staticnodestoml}\"\]%" $confPath
|
||||
shopt -s nocasematch; if [[ "$OS" == "darwin"* ]]; then
|
||||
sed -i '' "s%static-nodes = \[\]%static-nodes = \[\"${staticnodestoml}\"\]%" $confPath
|
||||
else
|
||||
sed -i "s%static-nodes = \[\]%static-nodes = \[\"${staticnodestoml}\"\]%" $confPath
|
||||
fi
|
||||
rm ./tempStaticNodes.toml
|
||||
else
|
||||
echo "neither JSON nor TOML StaticNodes found"
|
||||
|
|
@ -71,12 +94,18 @@ if [[ -f ./tempTrustedNodes.toml ]]
|
|||
then
|
||||
echo "TOML TrustedNodes found"
|
||||
trustednodestoml=$(head -1 ./tempTrustedNodes.toml)
|
||||
sed -i '' "s%trusted-nodes = \[\]%trusted-nodes = \[\"${trustednodestoml}\"\]%" $confPath
|
||||
shopt -s nocasematch; if [[ "$OS" == "darwin"* ]]; then
|
||||
sed -i '' "s%trusted-nodes = \[\]%trusted-nodes = \[\"${trustednodestoml}\"\]%" $confPath
|
||||
else
|
||||
sed -i "s%trusted-nodes = \[\]%trusted-nodes = \[\"${trustednodestoml}\"\]%" $confPath
|
||||
fi
|
||||
rm ./tempTrustedNodes.toml
|
||||
else
|
||||
echo "neither JSON nor TOML TrustedNodes found"
|
||||
fi
|
||||
|
||||
printf "\n"
|
||||
|
||||
# comment flags in $configPath that were not passed through $startPath
|
||||
# SHA1 hash of `tempStart` -> `3305fe263dd4a999d58f96deb064e21bb70123d9`
|
||||
sed "s%bor --%go run getconfig.go ${confPath} --%" $startPath > $tmpDir/3305fe263dd4a999d58f96deb064e21bb70123d9.sh
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
package bor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
@ -172,8 +173,10 @@ func buildNextBlock(t *testing.T, _bor consensus.Engine, chain *core.BlockChain,
|
|||
b.addTxWithChain(chain, state, tx, addr)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Finalize and seal the block
|
||||
block, _ := _bor.FinalizeAndAssemble(chain, b.header, state, b.txs, nil, b.receipts)
|
||||
block, _ := _bor.FinalizeAndAssemble(ctx, chain, b.header, state, b.txs, nil, b.receipts)
|
||||
|
||||
// Write state changes to db
|
||||
root, err := state.Commit(chain.Config().IsEIP158(b.header.Number))
|
||||
|
|
@ -187,7 +190,7 @@ func buildNextBlock(t *testing.T, _bor consensus.Engine, chain *core.BlockChain,
|
|||
|
||||
res := make(chan *types.Block, 1)
|
||||
|
||||
err = _bor.Seal(chain, block, res, nil)
|
||||
err = _bor.Seal(ctx, chain, block, res, nil)
|
||||
if err != nil {
|
||||
// an error case - sign manually
|
||||
sign(t, header, signer, borConfig)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
|
|
@ -37,7 +39,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
// StateTest checks transaction processing without block context.
|
||||
|
|
@ -217,15 +218,16 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
|||
|
||||
// Prepare the EVM.
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
|
||||
context.GetHash = vmTestBlockHash
|
||||
context.BaseFee = baseFee
|
||||
evmContext := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
|
||||
evmContext.GetHash = vmTestBlockHash
|
||||
evmContext.BaseFee = baseFee
|
||||
if t.json.Env.Random != nil {
|
||||
rnd := common.BigToHash(t.json.Env.Random)
|
||||
context.Random = &rnd
|
||||
context.Difficulty = big.NewInt(0)
|
||||
evmContext.Random = &rnd
|
||||
evmContext.Difficulty = big.NewInt(0)
|
||||
}
|
||||
evm := vm.NewEVM(context, txContext, statedb, config, vmconfig)
|
||||
|
||||
evm := vm.NewEVM(evmContext, txContext, statedb, config, vmconfig)
|
||||
// Execute the message.
|
||||
snapshot := statedb.Snapshot()
|
||||
gaspool := new(core.GasPool)
|
||||
|
|
|
|||
Loading…
Reference in a new issue