mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Bor fixes (#3553)
* Integration to work with bor * Turn off validator set check * disable verifySeal, add skeleton of postExec stage * Pass around syscall * Print * Print more * Default heimdall values for integration * restore contract * Print * Print * Print * Print * Print * Print * Print * Print * Fix nonce of system contract * Remove prints * Revert some more printing * More fixes * Print log * Fix transfer log * More printing * More printing * Print * Print * Print * Print * Print * Print * Print * Fix validaor reward * Remove printing * Remove more prints * Less printing * Fetch validators from heimdall * Remove syscall from Seal and CalcDifficulty * Remove syscall from Prepare * Print * Remove DNS discovery * Print apply snapshot * Print * Chunk up snapshot generation * Chunk up snapshot generation * Better logs when snapshotting * Handle parents * Prevent shadowing of snap * Fix heimdall fetch * Logging fixes * Save generated snapshots * Add header * Less logging Co-authored-by: Alexey Sharp <alexeysharp@Alexeys-iMac.local> Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro.local>
This commit is contained in:
parent
ee488020dd
commit
17b2a9ba93
@ -1109,6 +1109,9 @@ func newSync(ctx context.Context, db kv.RwDB, miningConfig *params.MiningConfig)
|
||||
} else if chainConfig.Parlia != nil {
|
||||
consensusConfig := ¶ms.ParliaConfig{DBPath: filepath.Join(datadir, "parlia")}
|
||||
engine = ethconfig.CreateConsensusEngine(chainConfig, logger, consensusConfig, config.Miner.Notify, config.Miner.Noverify, "", true, datadir)
|
||||
} else if chainConfig.Bor != nil {
|
||||
consensusConfig := &config.Bor
|
||||
engine = ethconfig.CreateConsensusEngine(chainConfig, logger, consensusConfig, config.Miner.Notify, config.Miner.Noverify, "http://localhost:1317", false, datadir)
|
||||
} else { //ethash
|
||||
engine = ethash.NewFaker()
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/btree"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/erigon/accounts/abi"
|
||||
@ -223,9 +224,8 @@ type Bor struct {
|
||||
|
||||
// scope event.SubscriptionScope
|
||||
// The fields below are for testing only
|
||||
fakeDiff bool // Skip difficulty verifications
|
||||
|
||||
sysCall consensus.SystemCall
|
||||
fakeDiff bool // Skip difficulty verifications
|
||||
spanCache *btree.BTree
|
||||
}
|
||||
|
||||
// New creates a Matic Bor consensus engine.
|
||||
@ -261,6 +261,7 @@ func New(
|
||||
GenesisContractsClient: genesisContractsClient,
|
||||
HeimdallClient: heimdallClient,
|
||||
WithoutHeimdall: withoutHeimdall,
|
||||
spanCache: btree.New(32),
|
||||
}
|
||||
|
||||
// make sure we can decode all the GenesisAlloc in the BorConfig.
|
||||
@ -429,97 +430,130 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t
|
||||
func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
|
||||
// Search for a snapshot in memory or on disk for checkpoints
|
||||
var (
|
||||
headers []*types.Header
|
||||
snap *Snapshot
|
||||
snap *Snapshot
|
||||
)
|
||||
|
||||
for snap == nil {
|
||||
// If an in-memory snapshot was found, use that
|
||||
if s, ok := c.recents.Get(hash); ok {
|
||||
snap = s.(*Snapshot)
|
||||
break
|
||||
}
|
||||
|
||||
// If an on-disk checkpoint snapshot can be found, use that
|
||||
if number%checkpointInterval == 0 {
|
||||
if s, err := loadSnapshot(c.config, c.signatures, c.DB, hash); err == nil {
|
||||
log.Trace("Loaded snapshot from disk", "number", number, "hash", hash)
|
||||
snap = s
|
||||
cont := true // Continue applying snapshots
|
||||
limit := 256
|
||||
for cont {
|
||||
var headersList [][]*types.Header // List of lists because we will apply headers to snapshot such that we can persist snapshot after every list
|
||||
var headers []*types.Header
|
||||
h := hash
|
||||
n := number
|
||||
p := parents
|
||||
cont = false
|
||||
for snap == nil {
|
||||
// If an in-memory snapshot was found, use that
|
||||
if s, ok := c.recents.Get(h); ok {
|
||||
snap = s.(*Snapshot)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If we're at the genesis, snapshot the initial state. Alternatively if we're
|
||||
// at a checkpoint block without a parent (light client CHT), or we have piled
|
||||
// up more headers than allowed to be reorged (chain reinit from a freezer),
|
||||
// consider the checkpoint trusted and snapshot it.
|
||||
// TODO fix this
|
||||
if number == 0 {
|
||||
checkpoint := chain.GetHeaderByNumber(number)
|
||||
if checkpoint != nil {
|
||||
// get checkpoint data
|
||||
hash := checkpoint.Hash()
|
||||
|
||||
// get validators and current span
|
||||
validators, err := c.GetCurrentValidators(number + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// If an on-disk checkpoint snapshot can be found, use that
|
||||
if n%checkpointInterval == 0 {
|
||||
if s, err := loadSnapshot(c.config, c.signatures, c.DB, h); err == nil {
|
||||
log.Trace("Loaded snapshot from disk", "number", n, "hash", h)
|
||||
snap = s
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// new snap shot
|
||||
snap = newSnapshot(c.config, c.signatures, number, hash, validators)
|
||||
if err := snap.store(c.DB); err != nil {
|
||||
return nil, err
|
||||
// If we're at the genesis, snapshot the initial state. Alternatively if we're
|
||||
// at a checkpoint block without a parent (light client CHT), or we have piled
|
||||
// up more headers than allowed to be reorged (chain reinit from a freezer),
|
||||
// consider the checkpoint trusted and snapshot it.
|
||||
// TODO fix this
|
||||
if n == 0 {
|
||||
checkpoint := chain.GetHeaderByNumber(n)
|
||||
if checkpoint != nil {
|
||||
// get checkpoint data
|
||||
h := checkpoint.Hash()
|
||||
|
||||
// get validators and current span
|
||||
validators, err := c.GetCurrentValidators(n + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// new snap shot
|
||||
snap = newSnapshot(c.config, c.signatures, n, h, validators)
|
||||
if err := snap.store(c.DB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Info("Stored checkpoint snapshot to disk", "number", n, "hash", h)
|
||||
break
|
||||
}
|
||||
log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash)
|
||||
break
|
||||
}
|
||||
|
||||
// No snapshot for this header, gather the header and move backward
|
||||
var header *types.Header
|
||||
if len(p) > 0 {
|
||||
// If we have explicit parents, pick from there (enforced)
|
||||
header = p[len(p)-1]
|
||||
if header.Hash() != h || header.Number.Uint64() != n {
|
||||
return nil, consensus.ErrUnknownAncestor
|
||||
}
|
||||
p = p[:len(p)-1]
|
||||
} else {
|
||||
// No explicit parents (or no more left), reach out to the database
|
||||
header = chain.GetHeader(h, n)
|
||||
if header == nil {
|
||||
return nil, consensus.ErrUnknownAncestor
|
||||
}
|
||||
}
|
||||
if n%checkpointInterval == 0 && len(headers) > 0 {
|
||||
headersList = append(headersList, headers)
|
||||
if len(headersList) > limit {
|
||||
headersList = headersList[1:]
|
||||
cont = true
|
||||
}
|
||||
headers = nil
|
||||
}
|
||||
headers = append(headers, header)
|
||||
n--
|
||||
h = header.ParentHash
|
||||
}
|
||||
|
||||
// No snapshot for this header, gather the header and move backward
|
||||
var header *types.Header
|
||||
if len(parents) > 0 {
|
||||
// If we have explicit parents, pick from there (enforced)
|
||||
header = parents[len(parents)-1]
|
||||
if header.Hash() != hash || header.Number.Uint64() != number {
|
||||
return nil, consensus.ErrUnknownAncestor
|
||||
}
|
||||
parents = parents[:len(parents)-1]
|
||||
} else {
|
||||
// No explicit parents (or no more left), reach out to the database
|
||||
header = chain.GetHeader(hash, number)
|
||||
if header == nil {
|
||||
return nil, consensus.ErrUnknownAncestor
|
||||
}
|
||||
// check if snapshot is nil
|
||||
if snap == nil {
|
||||
return nil, fmt.Errorf("unknown error while retrieving snapshot at block number %v", n)
|
||||
}
|
||||
headers = append(headers, header)
|
||||
number, hash = number-1, header.ParentHash
|
||||
}
|
||||
|
||||
// check if snapshot is nil
|
||||
if snap == nil {
|
||||
return nil, fmt.Errorf("Unknown error while retrieving snapshot at block number %v", number)
|
||||
}
|
||||
|
||||
// Previous snapshot found, apply any pending headers on top of it
|
||||
for i := 0; i < len(headers)/2; i++ {
|
||||
headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
|
||||
}
|
||||
|
||||
snap, err := snap.apply(headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.recents.Add(snap.Hash, snap)
|
||||
|
||||
// If we've generated a new checkpoint snapshot, save to disk
|
||||
if snap.Number%checkpointInterval == 0 && len(headers) > 0 {
|
||||
if err = snap.store(c.DB); err != nil {
|
||||
return nil, err
|
||||
if len(headers) > 0 {
|
||||
headersList = append(headersList, headers)
|
||||
}
|
||||
|
||||
// Previous snapshot found, apply any pending headers on top of it
|
||||
if cont {
|
||||
lastList := headersList[len(headersList)-1]
|
||||
firstList := headersList[0]
|
||||
log.Info("Applying headers to snapshot", "from", lastList[len(lastList)-1].Number.Uint64(), "to", firstList[0].Number.Uint64())
|
||||
}
|
||||
for i := 0; i < len(headersList)/2; i++ {
|
||||
headersList[i], headersList[len(headersList)-1-i] = headersList[len(headersList)-1-i], headersList[i]
|
||||
}
|
||||
for j := 0; j < len(headersList); j++ {
|
||||
hs := headersList[j]
|
||||
for i := 0; i < len(hs)/2; i++ {
|
||||
hs[i], hs[len(hs)-1-i] = hs[len(hs)-1-i], hs[i]
|
||||
}
|
||||
var err error
|
||||
snap, err = snap.apply(hs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.recents.Add(snap.Hash, snap)
|
||||
// We've generated a new checkpoint snapshot, save to disk
|
||||
if err = snap.store(c.DB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Trace("Stored snapshot to disk", "number", snap.Number, "hash", snap.Hash)
|
||||
}
|
||||
if cont {
|
||||
snap = nil
|
||||
}
|
||||
log.Trace("Stored snapshot to disk", "number", snap.Number, "hash", snap.Hash)
|
||||
}
|
||||
return snap, err
|
||||
|
||||
return snap, nil
|
||||
}
|
||||
|
||||
// VerifyUncles implements consensus.Engine, always returning an error for any
|
||||
@ -549,17 +583,17 @@ func (c *Bor) verifySeal(chain consensus.ChainHeaderReader, header *types.Header
|
||||
if number == 0 {
|
||||
return errUnknownBlock
|
||||
}
|
||||
// Retrieve the snapshot needed to verify this header and cache it
|
||||
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Resolve the authorization key and check against signers
|
||||
signer, err := ecrecover(header, c.signatures, c.config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Retrieve the snapshot needed to verify this header and cache it
|
||||
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !snap.ValidatorSet.HasAddress(signer.Bytes()) {
|
||||
// Check the UnauthorizedSignerError.Error() msg to see why we pass number-1
|
||||
return &UnauthorizedSignerError{number - 1, signer.Bytes()}
|
||||
@ -661,22 +695,19 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s
|
||||
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
|
||||
// rewards given.
|
||||
func (c *Bor) Finalize(config *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall) (types.Transactions, types.Receipts, error) {
|
||||
|
||||
// Update sysCall
|
||||
|
||||
var err error
|
||||
headerNumber := header.Number.Uint64()
|
||||
if headerNumber%c.config.Sprint == 0 {
|
||||
cx := chainContext{Chain: chain, Bor: c}
|
||||
// check and commit span
|
||||
if err := c.checkAndCommitSpan(state, header, cx); err != nil {
|
||||
if err := c.checkAndCommitSpan(state, header, cx, syscall); err != nil {
|
||||
log.Error("Error while committing span", "error", err)
|
||||
return nil, types.Receipts{}, err
|
||||
}
|
||||
|
||||
if !c.WithoutHeimdall {
|
||||
// commit states
|
||||
_, err = c.CommitStates(state, header, cx)
|
||||
_, err = c.CommitStates(state, header, cx, syscall)
|
||||
if err != nil {
|
||||
log.Error("Error while committing states", "error", err)
|
||||
return nil, types.Receipts{}, err
|
||||
@ -738,7 +769,7 @@ func (c *Bor) FinalizeAndAssemble(chainConfig *params.ChainConfig, header *types
|
||||
cx := chainContext{Chain: chain, Bor: c}
|
||||
|
||||
// check and commit span
|
||||
err := c.checkAndCommitSpan(state, header, cx)
|
||||
err := c.checkAndCommitSpan(state, header, cx, syscall)
|
||||
if err != nil {
|
||||
log.Error("Error while committing span", "error", err)
|
||||
return nil, nil, types.Receipts{}, err
|
||||
@ -746,7 +777,7 @@ func (c *Bor) FinalizeAndAssemble(chainConfig *params.ChainConfig, header *types
|
||||
|
||||
if !c.WithoutHeimdall {
|
||||
// commit states
|
||||
_, err = c.CommitStates(state, header, cx)
|
||||
_, err = c.CommitStates(state, header, cx, syscall)
|
||||
if err != nil {
|
||||
log.Error("Error while committing states", "error", err)
|
||||
return nil, nil, types.Receipts{}, err
|
||||
@ -913,7 +944,7 @@ func (c *Bor) Close() error {
|
||||
}
|
||||
|
||||
// GetCurrentSpan get current span from contract
|
||||
func (c *Bor) GetCurrentSpan(header *types.Header, state *state.IntraBlockState, chain chainContext) (*Span, error) {
|
||||
func (c *Bor) GetCurrentSpan(header *types.Header, state *state.IntraBlockState, chain chainContext, syscall consensus.SystemCall) (*Span, error) {
|
||||
|
||||
// method
|
||||
method := "getCurrentSpan"
|
||||
@ -923,7 +954,7 @@ func (c *Bor) GetCurrentSpan(header *types.Header, state *state.IntraBlockState,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := c.sysCall(common.HexToAddress(c.config.ValidatorContract), data)
|
||||
result, err := syscall(common.HexToAddress(c.config.ValidatorContract), data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -949,56 +980,27 @@ func (c *Bor) GetCurrentSpan(header *types.Header, state *state.IntraBlockState,
|
||||
}
|
||||
|
||||
// GetCurrentValidators get current validators
|
||||
func (c *Bor) GetCurrentValidators(blockNumber uint64) ([]*Validator, error) { // method
|
||||
method := "getBorValidators"
|
||||
|
||||
data, err := c.validatorSetABI.Pack(method, big.NewInt(0).SetUint64(blockNumber))
|
||||
func (c *Bor) GetCurrentValidators(blockNumber uint64) ([]*Validator, error) {
|
||||
span, err := c.getSpanForBlock(blockNumber)
|
||||
if err != nil {
|
||||
log.Error("Unable to pack tx for getValidator", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := c.sysCall(common.HexToAddress(c.config.ValidatorContract), data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var (
|
||||
ret0 = new([]common.Address)
|
||||
ret1 = new([]*big.Int)
|
||||
)
|
||||
out := &[]interface{}{
|
||||
ret0,
|
||||
ret1,
|
||||
}
|
||||
|
||||
if err := c.validatorSetABI.UnpackIntoInterface(out, method, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
valz := make([]*Validator, len(*ret0))
|
||||
for i, a := range *ret0 {
|
||||
valz[i] = &Validator{
|
||||
Address: a,
|
||||
VotingPower: (*ret1)[i].Int64(),
|
||||
}
|
||||
}
|
||||
|
||||
return valz, nil
|
||||
return span.ValidatorSet.Validators, nil
|
||||
}
|
||||
|
||||
func (c *Bor) checkAndCommitSpan(
|
||||
state *state.IntraBlockState,
|
||||
header *types.Header,
|
||||
chain chainContext,
|
||||
syscall consensus.SystemCall,
|
||||
) error {
|
||||
headerNumber := header.Number.Uint64()
|
||||
span, err := c.GetCurrentSpan(header, state, chain)
|
||||
span, err := c.GetCurrentSpan(header, state, chain, syscall)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.needToCommitSpan(span, headerNumber) {
|
||||
err := c.fetchAndCommitSpan(span.ID+1, state, header, chain)
|
||||
err := c.fetchAndCommitSpan(span.ID+1, state, header, chain, syscall)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -1023,16 +1025,64 @@ func (c *Bor) needToCommitSpan(span *Span, headerNumber uint64) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Bor) getSpanForBlock(blockNum uint64) (*HeimdallSpan, error) {
|
||||
log.Info("Getting span", "for block", blockNum)
|
||||
var span *HeimdallSpan
|
||||
c.spanCache.AscendGreaterOrEqual(&HeimdallSpan{Span: Span{EndBlock: blockNum}}, func(item btree.Item) bool {
|
||||
span = item.(*HeimdallSpan)
|
||||
return false
|
||||
})
|
||||
if span == nil {
|
||||
// Span with high enough block number is not loaded
|
||||
var spanID uint64
|
||||
if c.spanCache.Len() > 0 {
|
||||
spanID = c.spanCache.Max().(*HeimdallSpan).ID + 1
|
||||
}
|
||||
for span == nil || span.EndBlock < blockNum {
|
||||
var heimdallSpan HeimdallSpan
|
||||
log.Info("Span with high enough block number is not loaded", "fetching span", spanID)
|
||||
response, err := c.HeimdallClient.FetchWithRetry(fmt.Sprintf("bor/span/%d", spanID), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
span = &heimdallSpan
|
||||
c.spanCache.ReplaceOrInsert(span)
|
||||
spanID++
|
||||
}
|
||||
} else {
|
||||
for span.StartBlock > blockNum {
|
||||
// Span wit low enough block number is not loaded
|
||||
var spanID uint64 = span.ID - 1
|
||||
var heimdallSpan HeimdallSpan
|
||||
log.Info("Span with low enough block number is not loaded", "fetching span", spanID)
|
||||
response, err := c.HeimdallClient.FetchWithRetry(fmt.Sprintf("bor/span/%d", spanID), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
span = &heimdallSpan
|
||||
c.spanCache.ReplaceOrInsert(span)
|
||||
}
|
||||
}
|
||||
return span, nil
|
||||
}
|
||||
|
||||
func (c *Bor) fetchAndCommitSpan(
|
||||
newSpanID uint64,
|
||||
state *state.IntraBlockState,
|
||||
header *types.Header,
|
||||
chain chainContext,
|
||||
syscall consensus.SystemCall,
|
||||
) error {
|
||||
var heimdallSpan HeimdallSpan
|
||||
|
||||
if c.WithoutHeimdall {
|
||||
s, err := c.getNextHeimdallSpanForTest(newSpanID, state, header, chain)
|
||||
s, err := c.getNextHeimdallSpanForTest(newSpanID, state, header, chain, syscall)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1051,9 +1101,9 @@ func (c *Bor) fetchAndCommitSpan(
|
||||
// check if chain id matches with heimdall span
|
||||
if heimdallSpan.ChainID != c.chainConfig.ChainID.String() {
|
||||
return fmt.Errorf(
|
||||
"Chain id proposed span, %s, and bor chain id, %s, doesn't match",
|
||||
"chain id proposed span, %s, and bor chain id, %s, doesn't match",
|
||||
heimdallSpan.ChainID,
|
||||
c.chainConfig.ChainID,
|
||||
c.chainConfig.ChainID.String(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1079,7 +1129,7 @@ func (c *Bor) fetchAndCommitSpan(
|
||||
|
||||
// method
|
||||
method := "commitSpan"
|
||||
log.Info("✅ Committing new span",
|
||||
log.Debug("✅ Committing new span",
|
||||
"id", heimdallSpan.ID,
|
||||
"startBlock", heimdallSpan.StartBlock,
|
||||
"endBlock", heimdallSpan.EndBlock,
|
||||
@ -1100,7 +1150,7 @@ func (c *Bor) fetchAndCommitSpan(
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = c.sysCall(common.HexToAddress(c.config.ValidatorContract), data)
|
||||
_, err = syscall(common.HexToAddress(c.config.ValidatorContract), data)
|
||||
// apply message
|
||||
return err
|
||||
}
|
||||
@ -1110,10 +1160,11 @@ func (c *Bor) CommitStates(
|
||||
state *state.IntraBlockState,
|
||||
header *types.Header,
|
||||
chain chainContext,
|
||||
syscall consensus.SystemCall,
|
||||
) ([]*types.StateSyncData, error) {
|
||||
stateSyncs := make([]*types.StateSyncData, 0)
|
||||
number := header.Number.Uint64()
|
||||
_lastStateID, err := c.GenesisContractsClient.LastStateId(header, state, chain, c)
|
||||
_lastStateID, err := c.GenesisContractsClient.LastStateId(header, state, chain, c, syscall)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1153,7 +1204,7 @@ func (c *Bor) CommitStates(
|
||||
}
|
||||
stateSyncs = append(stateSyncs, &stateData)
|
||||
|
||||
if err := c.GenesisContractsClient.CommitState(eventRecord, state, header, chain, c); err != nil {
|
||||
if err := c.GenesisContractsClient.CommitState(eventRecord, state, header, chain, c, syscall); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lastStateID++
|
||||
@ -1182,9 +1233,10 @@ func (c *Bor) getNextHeimdallSpanForTest(
|
||||
state *state.IntraBlockState,
|
||||
header *types.Header,
|
||||
chain chainContext,
|
||||
syscall consensus.SystemCall,
|
||||
) (*HeimdallSpan, error) {
|
||||
headerNumber := header.Number.Uint64()
|
||||
span, err := c.GetCurrentSpan(header, state, chain)
|
||||
span, err := c.GetCurrentSpan(header, state, chain, syscall)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/ledgerwatch/erigon/accounts/abi"
|
||||
"github.com/ledgerwatch/erigon/common"
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/core/state"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
@ -46,6 +47,7 @@ func (gc *GenesisContractsClient) CommitState(
|
||||
header *types.Header,
|
||||
chCtx chainContext,
|
||||
c *Bor,
|
||||
syscall consensus.SystemCall,
|
||||
) error {
|
||||
eventRecord := event.BuildEventRecord()
|
||||
recordBytes, err := rlp.EncodeToBytes(eventRecord)
|
||||
@ -60,7 +62,7 @@ func (gc *GenesisContractsClient) CommitState(
|
||||
return err
|
||||
}
|
||||
log.Trace("→ committing new state", "eventRecord", event.String())
|
||||
_, err = c.sysCall(common.HexToAddress(gc.StateReceiverContract), data)
|
||||
_, err = syscall(common.HexToAddress(gc.StateReceiverContract), data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -71,6 +73,7 @@ func (gc *GenesisContractsClient) LastStateId(header *types.Header,
|
||||
state *state.IntraBlockState,
|
||||
chain chainContext,
|
||||
c *Bor,
|
||||
syscall consensus.SystemCall,
|
||||
) (*big.Int, error) {
|
||||
method := "lastStateId"
|
||||
data, err := gc.stateReceiverABI.Pack(method)
|
||||
@ -79,7 +82,7 @@ func (gc *GenesisContractsClient) LastStateId(header *types.Header,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := c.sysCall(common.HexToAddress(gc.StateReceiverContract), data)
|
||||
result, err := syscall(common.HexToAddress(gc.StateReceiverContract), data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func (h *HeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*Event
|
||||
eventRecords := make([]*EventRecordWithTime, 0)
|
||||
for {
|
||||
queryParams := fmt.Sprintf("from-id=%d&to-time=%d&limit=%d", fromID, to, stateFetchLimit)
|
||||
log.Info("Fetching state sync events", "queryParams", queryParams)
|
||||
log.Trace("Fetching state sync events", "queryParams", queryParams)
|
||||
response, err := h.FetchWithRetry("clerk/event-record/list", queryParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1,5 +1,9 @@
|
||||
package bor
|
||||
|
||||
import (
|
||||
"github.com/google/btree"
|
||||
)
|
||||
|
||||
// Span represents a current bor span
|
||||
type Span struct {
|
||||
ID uint64 `json:"span_id" yaml:"span_id"`
|
||||
@ -14,3 +18,12 @@ type HeimdallSpan struct {
|
||||
SelectedProducers []Validator `json:"selected_producers" yaml:"selected_producers"`
|
||||
ChainID string `json:"bor_chain_id" yaml:"bor_chain_id"`
|
||||
}
|
||||
|
||||
func (hs *HeimdallSpan) Less(other btree.Item) bool {
|
||||
otherHs := other.(*HeimdallSpan)
|
||||
if hs.EndBlock == 0 || otherHs.EndBlock == 0 {
|
||||
// if endblock is not specified in one of the items, allow search by ID
|
||||
return hs.ID < otherHs.ID
|
||||
}
|
||||
return hs.EndBlock < otherHs.EndBlock
|
||||
}
|
||||
|
@ -351,6 +351,20 @@ func SysCallContract(contract common.Address, data []byte, chainConfig params.Ch
|
||||
// Create a new context to be used in the EVM environment
|
||||
blockContext := NewEVMBlockContext(header, nil, engine, &state.SystemAddress, nil)
|
||||
evm := vm.NewEVM(blockContext, NewEVMTxContext(msg), ibs, &chainConfig, vmConfig)
|
||||
if chainConfig.Bor != nil {
|
||||
ret, _, err := evm.Call(
|
||||
vm.AccountRef(msg.From()),
|
||||
*msg.To(),
|
||||
msg.Data(),
|
||||
msg.Gas(),
|
||||
msg.Value(),
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
res, err := ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -429,10 +429,15 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
|
||||
amount.Mul(amount, effectiveTip) // gasUsed * effectiveTip = how much goes to the block producer (miner, validator)
|
||||
if st.isParlia {
|
||||
st.state.AddBalance(consensus.SystemAddress, amount)
|
||||
} else if london && st.isBor {
|
||||
burntContractAddress := common.HexToAddress(st.evm.ChainConfig().Bor.CalculateBurntContract(st.evm.Context().BlockNumber))
|
||||
burnAmount := new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gasUsed()), st.evm.Context().BaseFee)
|
||||
st.state.AddBalance(burntContractAddress, burnAmount)
|
||||
} else {
|
||||
st.state.AddBalance(st.evm.Context().Coinbase, amount)
|
||||
}
|
||||
if st.isBor {
|
||||
if london {
|
||||
burntContractAddress := common.HexToAddress(st.evm.ChainConfig().Bor.CalculateBurntContract(st.evm.Context().BlockNumber))
|
||||
burnAmount := new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gasUsed()), st.evm.Context().BaseFee)
|
||||
st.state.AddBalance(burntContractAddress, burnAmount)
|
||||
}
|
||||
// Deprecating transfer log and will be removed in future fork. PLEASE DO NOT USE this transfer log going forward. Parameters won't get updated as expected going forward with EIP1559
|
||||
// add transfer log
|
||||
output1 := input1.Clone()
|
||||
@ -449,8 +454,6 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
|
||||
output1.Sub(output1, amount),
|
||||
output2.Add(output2, amount),
|
||||
)
|
||||
} else {
|
||||
st.state.AddBalance(st.evm.Context().Coinbase, amount)
|
||||
}
|
||||
|
||||
return &ExecutionResult{
|
||||
|
84
eth/stagedsync/stage_postexec.go
Normal file
84
eth/stagedsync/stage_postexec.go
Normal file
@ -0,0 +1,84 @@
|
||||
package stagedsync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
)
|
||||
|
||||
// PostExec stage is run after execution stage to peform extra verifications that are only possible when state is available.
|
||||
// It is used for consensus engines which keep validators inside smart contracts (Bor, AuRa)
|
||||
|
||||
type PostExecCfg struct {
|
||||
db kv.RwDB
|
||||
borDb kv.RwDB
|
||||
}
|
||||
|
||||
func StagePostExecCfg(db kv.RwDB, borDb kv.RwDB) PostExecCfg {
|
||||
return PostExecCfg{
|
||||
db: db,
|
||||
borDb: borDb,
|
||||
}
|
||||
}
|
||||
|
||||
func SpawnPostExecStage(s *StageState, tx kv.RwTx, cfg PostExecCfg, ctx context.Context) error {
|
||||
useExternalTx := tx != nil
|
||||
if !useExternalTx {
|
||||
var err error
|
||||
tx, err = cfg.db.BeginRw(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
}
|
||||
|
||||
//logPrefix := s.LogPrefix()
|
||||
to, err := s.ExecutionAt(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.BlockNumber == to {
|
||||
// we already did hash check for this block
|
||||
// we don't do the obvious `if s.BlockNumber > to` to support reorgs more naturally
|
||||
return nil
|
||||
}
|
||||
if s.BlockNumber > to {
|
||||
return fmt.Errorf("hashstate: promotion backwards from %d to %d", s.BlockNumber, to)
|
||||
}
|
||||
|
||||
if err = s.Update(tx, to); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !useExternalTx {
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnwindPostExecStage(u *UnwindState, s *StageState, tx kv.RwTx, cfg PostExecCfg, ctx context.Context) (err error) {
|
||||
useExternalTx := tx != nil
|
||||
if !useExternalTx {
|
||||
tx, err = cfg.db.BeginRw(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
}
|
||||
|
||||
//logPrefix := u.LogPrefix()
|
||||
|
||||
if err = u.Done(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
if !useExternalTx {
|
||||
if err = tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -164,18 +164,12 @@ func KnownDNSNetwork(genesis common.Hash, protocol string) string {
|
||||
switch genesis {
|
||||
case MainnetGenesisHash:
|
||||
net = "mainnet"
|
||||
case SepoliaGenesisHash:
|
||||
net = "sepolia"
|
||||
case RopstenGenesisHash:
|
||||
net = "ropsten"
|
||||
case RinkebyGenesisHash:
|
||||
net = "rinkeby"
|
||||
case GoerliGenesisHash:
|
||||
net = "goerli"
|
||||
case MumbaiGenesisHash:
|
||||
net = "mumbai"
|
||||
case BorMainnetGenesisHash:
|
||||
net = "bor-mainnet"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
@ -251,7 +251,6 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I
|
||||
hb.nodeStack[len(hb.nodeStack)-1] = s
|
||||
if hb.trace {
|
||||
fmt.Printf("Stack depth: %d\n", len(hb.nodeStack))
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -321,11 +320,11 @@ func (hb *HashBuilder) accountLeafHashWithKey(key []byte, popped int) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Printf("accountLeafHashWithKey [%x]=>[%x]\nHash [%x]\n", key, val, hb.hashBuf[:])
|
||||
if popped > 0 {
|
||||
hb.hashStack = hb.hashStack[:len(hb.hashStack)-popped*hashStackStride]
|
||||
hb.nodeStack = hb.nodeStack[:len(hb.nodeStack)-popped]
|
||||
}
|
||||
//fmt.Printf("accountLeafHashWithKey [%x]=>[%x]\nHash [%x]\n", key, val, hb.hashBuf[:])
|
||||
hb.hashStack = append(hb.hashStack, hb.hashBuf[:]...)
|
||||
hb.nodeStack = append(hb.nodeStack, nil)
|
||||
if hb.trace {
|
||||
|
Loading…
Reference in New Issue
Block a user