mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 11:41:19 +00:00
prototype of ValidataChain (#7921)
This commit is contained in:
parent
837ffb5b7e
commit
9d3551f8cf
@ -36,7 +36,7 @@ func NewEth1Execution(db kv.RwDB, blockReader services.FullBlockReader) *Eth1Exe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Eth1Execution) InsertHeaders(ctx context.Context, req *execution.InsertHeadersRequest) (*execution.EmptyMessage, error) {
|
func (e *Eth1Execution) InsertHeaders(ctx context.Context, req *execution.InsertHeadersRequest) (*execution.InsertionResult, error) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
tx, err := e.db.BeginRw(ctx)
|
tx, err := e.db.BeginRw(ctx)
|
||||||
@ -54,10 +54,12 @@ func (e *Eth1Execution) InsertHeaders(ctx context.Context, req *execution.Insert
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &execution.EmptyMessage{}, tx.Commit()
|
return &execution.InsertionResult{
|
||||||
|
Result: execution.ValidationStatus_Success,
|
||||||
|
}, tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Eth1Execution) InsertBodies(ctx context.Context, req *execution.InsertBodiesRequest) (*execution.EmptyMessage, error) {
|
func (e *Eth1Execution) InsertBodies(ctx context.Context, req *execution.InsertBodiesRequest) (*execution.InsertionResult, error) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
tx, err := e.db.BeginRw(ctx)
|
tx, err := e.db.BeginRw(ctx)
|
||||||
@ -94,7 +96,9 @@ func (e *Eth1Execution) InsertBodies(ctx context.Context, req *execution.InsertB
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &execution.EmptyMessage{}, tx.Commit()
|
return &execution.InsertionResult{
|
||||||
|
Result: execution.ValidationStatus_Success,
|
||||||
|
}, tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
type canonicalEntry struct {
|
type canonicalEntry struct {
|
||||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module github.com/ledgerwatch/erigon
|
|||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230714001632-a0450f4fddd1
|
github.com/ledgerwatch/erigon-lib v0.0.0-20230723163836-9e08d02f75b8
|
||||||
github.com/ledgerwatch/erigon-snapshot v1.2.1-0.20230622075030-1d69651854c2
|
github.com/ledgerwatch/erigon-snapshot v1.2.1-0.20230622075030-1d69651854c2
|
||||||
github.com/ledgerwatch/log/v3 v3.8.0
|
github.com/ledgerwatch/log/v3 v3.8.0
|
||||||
github.com/ledgerwatch/secp256k1 v1.0.0
|
github.com/ledgerwatch/secp256k1 v1.0.0
|
||||||
|
4
go.sum
4
go.sum
@ -415,8 +415,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|||||||
github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0=
|
github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0=
|
||||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230714001632-a0450f4fddd1 h1:dSsZV1wEVixmc+aXO6fv2XyZ05JOrj4gGIuxoTPIjYM=
|
github.com/ledgerwatch/erigon-lib v0.0.0-20230723163836-9e08d02f75b8 h1:P8CdtNh0DDKhzTVnwuCQY1lg8Jn1N21nmSHGOl4Kjxo=
|
||||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230714001632-a0450f4fddd1/go.mod h1:S/p/qNKN8yFyBy0WjBVjATpm1uwjPmhdcrDmseWHBVQ=
|
github.com/ledgerwatch/erigon-lib v0.0.0-20230723163836-9e08d02f75b8/go.mod h1:ZkH1giM9x/HgdvjWzeCiOIx2lLDo98T/uvmRkG6xet0=
|
||||||
github.com/ledgerwatch/erigon-snapshot v1.2.1-0.20230622075030-1d69651854c2 h1:Ls2itRGHMOr2PbHRDA4g1HH8HQdwfJhRVfMPEaLQe94=
|
github.com/ledgerwatch/erigon-snapshot v1.2.1-0.20230622075030-1d69651854c2 h1:Ls2itRGHMOr2PbHRDA4g1HH8HQdwfJhRVfMPEaLQe94=
|
||||||
github.com/ledgerwatch/erigon-snapshot v1.2.1-0.20230622075030-1d69651854c2/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo=
|
github.com/ledgerwatch/erigon-snapshot v1.2.1-0.20230622075030-1d69651854c2/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo=
|
||||||
github.com/ledgerwatch/log/v3 v3.8.0 h1:gCpp7uGtIerEz1jKVPeDnbIopFPud9ZnCpBLlLBGqPU=
|
github.com/ledgerwatch/log/v3 v3.8.0 h1:gCpp7uGtIerEz1jKVPeDnbIopFPud9ZnCpBLlLBGqPU=
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
||||||
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
|
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
|
||||||
"github.com/ledgerwatch/erigon-lib/kv/memdb"
|
"github.com/ledgerwatch/erigon-lib/kv/memdb"
|
||||||
|
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||||
"github.com/ledgerwatch/erigon/core/types"
|
"github.com/ledgerwatch/erigon/core/types"
|
||||||
"github.com/ledgerwatch/erigon/turbo/execution/eth1"
|
"github.com/ledgerwatch/erigon/turbo/execution/eth1"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -20,7 +21,11 @@ func TestInsertGetterHeader(t *testing.T) {
|
|||||||
Difficulty: big.NewInt(0),
|
Difficulty: big.NewInt(0),
|
||||||
Number: big.NewInt(int64(bn)),
|
Number: big.NewInt(int64(bn)),
|
||||||
}
|
}
|
||||||
e := eth1.NewEthereumExecutionModule(nil, memdb.NewTestDB(t), nil, nil)
|
db := memdb.NewTestDB(t)
|
||||||
|
tx, _ := db.BeginRw(context.TODO())
|
||||||
|
rawdb.WriteTd(tx, libcommon.Hash{}, 1, libcommon.Big0)
|
||||||
|
tx.Commit()
|
||||||
|
e := eth1.NewEthereumExecutionModule(nil, db, nil, nil, nil)
|
||||||
_, err := e.InsertHeaders(context.TODO(), &execution.InsertHeadersRequest{
|
_, err := e.InsertHeaders(context.TODO(), &execution.InsertHeadersRequest{
|
||||||
Headers: []*execution.Header{
|
Headers: []*execution.Header{
|
||||||
eth1.HeaderToHeaderRPC(header),
|
eth1.HeaderToHeaderRPC(header),
|
||||||
@ -41,7 +46,7 @@ func TestInsertGetterBody(t *testing.T) {
|
|||||||
body := &types.RawBody{
|
body := &types.RawBody{
|
||||||
Transactions: txs,
|
Transactions: txs,
|
||||||
}
|
}
|
||||||
e := eth1.NewEthereumExecutionModule(nil, memdb.NewTestDB(t), nil, nil)
|
e := eth1.NewEthereumExecutionModule(nil, memdb.NewTestDB(t), nil, nil, nil)
|
||||||
_, err := e.InsertBodies(context.TODO(), &execution.InsertBodiesRequest{
|
_, err := e.InsertBodies(context.TODO(), &execution.InsertBodiesRequest{
|
||||||
Bodies: []*execution.BlockBody{
|
Bodies: []*execution.BlockBody{
|
||||||
eth1.ConvertRawBlockBodyToRpc(body, bn, bhash),
|
eth1.ConvertRawBlockBodyToRpc(body, bn, bhash),
|
||||||
|
@ -3,18 +3,20 @@ package eth1
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/anacrolix/sync"
|
|
||||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||||
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
||||||
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
|
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
|
||||||
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
|
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
|
||||||
"github.com/ledgerwatch/log/v3"
|
"github.com/ledgerwatch/log/v3"
|
||||||
|
"golang.org/x/sync/semaphore"
|
||||||
|
|
||||||
"github.com/ledgerwatch/erigon-lib/kv"
|
"github.com/ledgerwatch/erigon-lib/kv"
|
||||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||||
"github.com/ledgerwatch/erigon/core/types"
|
"github.com/ledgerwatch/erigon/core/types"
|
||||||
"github.com/ledgerwatch/erigon/eth/stagedsync"
|
"github.com/ledgerwatch/erigon/eth/stagedsync"
|
||||||
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
|
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
|
||||||
|
"github.com/ledgerwatch/erigon/turbo/engineapi/engine_helpers"
|
||||||
|
"github.com/ledgerwatch/erigon/turbo/engineapi/engine_types"
|
||||||
"github.com/ledgerwatch/erigon/turbo/services"
|
"github.com/ledgerwatch/erigon/turbo/services"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,20 +27,23 @@ type EthereumExecutionModule struct {
|
|||||||
|
|
||||||
// MDBX database
|
// MDBX database
|
||||||
db kv.RwDB // main database
|
db kv.RwDB // main database
|
||||||
lock sync.Mutex
|
semaphore *semaphore.Weighted
|
||||||
executionPipeline *stagedsync.Sync
|
executionPipeline *stagedsync.Sync
|
||||||
|
forkValidator *engine_helpers.ForkValidator
|
||||||
|
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
execution.UnimplementedExecutionServer
|
execution.UnimplementedExecutionServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEthereumExecutionModule(blockReader services.FullBlockReader, db kv.RwDB, executionPipeline *stagedsync.Sync, logger log.Logger) *EthereumExecutionModule {
|
func NewEthereumExecutionModule(blockReader services.FullBlockReader, db kv.RwDB, executionPipeline *stagedsync.Sync, forkValidator *engine_helpers.ForkValidator, logger log.Logger) *EthereumExecutionModule {
|
||||||
return &EthereumExecutionModule{
|
return &EthereumExecutionModule{
|
||||||
blockReader: blockReader,
|
blockReader: blockReader,
|
||||||
db: db,
|
db: db,
|
||||||
executionPipeline: executionPipeline,
|
executionPipeline: executionPipeline,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
forkValidator: forkValidator,
|
||||||
|
semaphore: semaphore.NewWeighted(1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +76,14 @@ func (e *EthereumExecutionModule) UpdateForkChoice(ctx context.Context, req *typ
|
|||||||
hash libcommon.Hash
|
hash libcommon.Hash
|
||||||
number uint64
|
number uint64
|
||||||
}
|
}
|
||||||
e.lock.Lock()
|
if !e.semaphore.TryAcquire(1) {
|
||||||
defer e.lock.Unlock()
|
return &execution.ForkChoiceReceipt{
|
||||||
|
LatestValidHash: gointerfaces.ConvertHashToH256(libcommon.Hash{}),
|
||||||
|
Status: execution.ValidationStatus_Busy,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
defer e.semaphore.Release(1)
|
||||||
|
|
||||||
tx, err := e.db.BeginRw(ctx)
|
tx, err := e.db.BeginRw(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -169,4 +180,53 @@ func (e *EthereumExecutionModule) UpdateForkChoice(ctx context.Context, req *typ
|
|||||||
}, tx.Commit()
|
}, tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EthereumExecutionModule) ValidateChain(ctx context.Context, req *execution.ValidationRequest) (*execution.ValidationReceipt, error) {
|
||||||
|
if !e.semaphore.TryAcquire(1) {
|
||||||
|
return &execution.ValidationReceipt{
|
||||||
|
LatestValidHash: gointerfaces.ConvertHashToH256(libcommon.Hash{}),
|
||||||
|
ValidationStatus: execution.ValidationStatus_Busy,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
defer e.semaphore.Release(1)
|
||||||
|
tx, err := e.db.BeginRw(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
blockHash := gointerfaces.ConvertH256ToHash(req.Hash)
|
||||||
|
header, err := e.blockReader.Header(ctx, tx, blockHash, req.Number)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := e.blockReader.BodyWithTransactions(ctx, tx, blockHash, req.Number)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if header == nil || body == nil {
|
||||||
|
return &execution.ValidationReceipt{
|
||||||
|
LatestValidHash: gointerfaces.ConvertHashToH256(libcommon.Hash{}),
|
||||||
|
MissingHash: req.Hash,
|
||||||
|
ValidationStatus: execution.ValidationStatus_MissingSegment,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
status, lvh, validationError, criticalError := e.forkValidator.ValidatePayload(tx, header, body.RawBody(), false)
|
||||||
|
if criticalError != nil {
|
||||||
|
return nil, criticalError
|
||||||
|
}
|
||||||
|
validationStatus := execution.ValidationStatus_Success
|
||||||
|
if status == engine_types.AcceptedStatus {
|
||||||
|
validationStatus = execution.ValidationStatus_MissingSegment
|
||||||
|
}
|
||||||
|
if status == engine_types.InvalidStatus || status == engine_types.InvalidBlockHashStatus || validationError != nil {
|
||||||
|
e.logger.Warn("ethereumExecutionModule.ValidateChain: chain %x is invalid. reason %s", blockHash, err)
|
||||||
|
validationStatus = execution.ValidationStatus_BadBlock
|
||||||
|
}
|
||||||
|
return &execution.ValidationReceipt{
|
||||||
|
ValidationStatus: validationStatus,
|
||||||
|
LatestValidHash: gointerfaces.ConvertHashToH256(lvh),
|
||||||
|
MissingHash: gointerfaces.ConvertHashToH256(libcommon.Hash{}), // TODO: implement
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Missing: NewPayload, AssembleBlock
|
// Missing: NewPayload, AssembleBlock
|
||||||
|
@ -9,9 +9,13 @@ import (
|
|||||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *EthereumExecutionModule) InsertBodies(ctx context.Context, req *execution.InsertBodiesRequest) (*execution.EmptyMessage, error) {
|
func (e *EthereumExecutionModule) InsertBodies(ctx context.Context, req *execution.InsertBodiesRequest) (*execution.InsertionResult, error) {
|
||||||
e.lock.Lock()
|
if !e.semaphore.TryAcquire(1) {
|
||||||
defer e.lock.Unlock()
|
return &execution.InsertionResult{
|
||||||
|
Result: execution.ValidationStatus_Busy,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
defer e.semaphore.Release(1)
|
||||||
tx, err := e.db.BeginRw(ctx)
|
tx, err := e.db.BeginRw(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ethereumExecutionModule.InsertBodies: could not begin transaction: %s", err)
|
return nil, fmt.Errorf("ethereumExecutionModule.InsertBodies: could not begin transaction: %s", err)
|
||||||
@ -26,12 +30,18 @@ func (e *EthereumExecutionModule) InsertBodies(ctx context.Context, req *executi
|
|||||||
return nil, fmt.Errorf("ethereumExecutionModule.InsertBodies: could not commit: %s", err)
|
return nil, fmt.Errorf("ethereumExecutionModule.InsertBodies: could not commit: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &execution.EmptyMessage{}, tx.Commit()
|
return &execution.InsertionResult{
|
||||||
|
Result: execution.ValidationStatus_Success,
|
||||||
|
}, tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EthereumExecutionModule) InsertHeaders(ctx context.Context, req *execution.InsertHeadersRequest) (*execution.EmptyMessage, error) {
|
func (e *EthereumExecutionModule) InsertHeaders(ctx context.Context, req *execution.InsertHeadersRequest) (*execution.InsertionResult, error) {
|
||||||
e.lock.Lock()
|
if !e.semaphore.TryAcquire(1) {
|
||||||
defer e.lock.Unlock()
|
return &execution.InsertionResult{
|
||||||
|
Result: execution.ValidationStatus_Busy,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
defer e.semaphore.Release(1)
|
||||||
tx, err := e.db.BeginRw(ctx)
|
tx, err := e.db.BeginRw(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: could not begin transaction: %s", err)
|
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: could not begin transaction: %s", err)
|
||||||
@ -42,13 +52,25 @@ func (e *EthereumExecutionModule) InsertHeaders(ctx context.Context, req *execut
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: cannot convert headers: %s", err)
|
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: cannot convert headers: %s", err)
|
||||||
}
|
}
|
||||||
|
// Parent's total difficulty
|
||||||
|
parentTd, err := rawdb.ReadTd(tx, header.ParentHash, header.Number.Uint64()-1)
|
||||||
|
if err != nil || parentTd == nil {
|
||||||
|
return nil, fmt.Errorf("parent's total difficulty not found with hash %x and height %d: %v", header.ParentHash, header.Number.Uint64()-1, err)
|
||||||
|
}
|
||||||
|
// Sum TDs.
|
||||||
|
td := parentTd.Add(parentTd, header.Difficulty)
|
||||||
if err := rawdb.WriteHeader(tx, header); err != nil {
|
if err := rawdb.WriteHeader(tx, header); err != nil {
|
||||||
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: could not insert: %s", err)
|
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: could not insert: %s", err)
|
||||||
}
|
}
|
||||||
|
if err := rawdb.WriteTd(tx, header.Hash(), header.Number.Uint64(), td); err != nil {
|
||||||
|
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: could not insert: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: could not commit: %s", err)
|
return nil, fmt.Errorf("ethereumExecutionModule.InsertHeaders: could not commit: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &execution.EmptyMessage{}, tx.Commit()
|
return &execution.InsertionResult{
|
||||||
|
Result: execution.ValidationStatus_Success,
|
||||||
|
}, tx.Commit()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user