diff --git a/pkg/beaconclient/databasewrite.go b/pkg/beaconclient/databasewrite.go index 62df98e..e620326 100644 --- a/pkg/beaconclient/databasewrite.go +++ b/pkg/beaconclient/databasewrite.go @@ -36,6 +36,11 @@ VALUES ($1, $2, $3, $4, $5) ON CONFLICT (slot, block_root) DO NOTHING` UpsertSignedBeaconBlockStmt string = ` INSERT INTO eth_beacon.signed_block (slot, block_root, parent_block_root, eth1_data_block_hash, mh_key) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (slot, block_root) DO NOTHING` + UpsertSignedBeaconBlockWithPayloadStmt string = ` +INSERT INTO eth_beacon.signed_block (slot, block_root, parent_block_root, eth1_data_block_hash, mh_key, + payload_block_number, payload_timestamp, payload_block_hash, + payload_parent_hash, payload_state_root, payload_receipts_root) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) ON CONFLICT (slot, block_root) DO NOTHING` // Statement to upsert to the eth_beacon.state table. UpsertBeaconState string = ` INSERT INTO eth_beacon.state (slot, state_root, mh_key) @@ -95,7 +100,7 @@ type DatabaseWriter struct { } func CreateDatabaseWrite(db sql.Database, slot int, stateRoot string, blockRoot string, parentBlockRoot string, - eth1DataBlockHash string, status string, rawSignedBeaconBlock *[]byte, rawBeaconState *[]byte, metrics *BeaconClientMetrics) (*DatabaseWriter, error) { + eth1DataBlockHash string, payloadSummary *ExecutionPayloadSummary, status string, rawSignedBeaconBlock *[]byte, rawBeaconState *[]byte, metrics *BeaconClientMetrics) (*DatabaseWriter, error) { ctx := context.Background() tx, err := db.Begin(ctx) if err != nil { @@ -110,7 +115,7 @@ func CreateDatabaseWrite(db sql.Database, slot int, stateRoot string, blockRoot Metrics: metrics, } dw.prepareSlotsModel(slot, stateRoot, blockRoot, status) - err = dw.prepareSignedBeaconBlockModel(slot, blockRoot, parentBlockRoot, eth1DataBlockHash) + err = dw.prepareSignedBeaconBlockModel(slot, blockRoot, parentBlockRoot, eth1DataBlockHash, payloadSummary) if err != nil { return nil, err } @@ -137,7 +142,8 @@ func (dw *DatabaseWriter) prepareSlotsModel(slot int, stateRoot string, blockRoo } // Create the model for the eth_beacon.signed_block table. -func (dw *DatabaseWriter) prepareSignedBeaconBlockModel(slot int, blockRoot string, parentBlockRoot string, eth1DataBlockHash string) error { +func (dw *DatabaseWriter) prepareSignedBeaconBlockModel(slot int, blockRoot string, parentBlockRoot string, eth1DataBlockHash string, + payloadSummary *ExecutionPayloadSummary) error { mhKey, err := MultihashKeyFromSSZRoot([]byte(dw.DbSlots.BlockRoot)) if err != nil { return err @@ -148,6 +154,7 @@ func (dw *DatabaseWriter) prepareSignedBeaconBlockModel(slot int, blockRoot stri ParentBlock: parentBlockRoot, Eth1DataBlockHash: eth1DataBlockHash, MhKey: mhKey, + ExecutionPayload: payloadSummary, } log.Debug("dw.DbSignedBeaconBlock: ", dw.DbSignedBeaconBlock) return nil @@ -257,9 +264,35 @@ func (dw *DatabaseWriter) upsertPublicBlocks(key string, data *[]byte) error { // Upsert to the eth_beacon.signed_block table. func (dw *DatabaseWriter) upsertSignedBeaconBlock() error { - _, err := dw.Tx.Exec(dw.Ctx, UpsertSignedBeaconBlockStmt, dw.DbSignedBeaconBlock.Slot, dw.DbSignedBeaconBlock.BlockRoot, dw.DbSignedBeaconBlock.ParentBlock, dw.DbSignedBeaconBlock.Eth1DataBlockHash, dw.DbSignedBeaconBlock.MhKey) + block := dw.DbSignedBeaconBlock + var err error + if nil != block.ExecutionPayload { + _, err = dw.Tx.Exec(dw.Ctx, + UpsertSignedBeaconBlockWithPayloadStmt, + block.Slot, + block.BlockRoot, + block.ParentBlock, + block.Eth1DataBlockHash, + block.MhKey, + block.ExecutionPayload.PayloadBlockNumber, + block.ExecutionPayload.PayloadTimestamp, + block.ExecutionPayload.PayloadBlockHash, + block.ExecutionPayload.PayloadParentHash, + block.ExecutionPayload.PayloadStateRoot, + block.ExecutionPayload.PayloadReceiptsRoot, + ) + } else { + _, err = dw.Tx.Exec(dw.Ctx, + UpsertSignedBeaconBlockStmt, + block.Slot, + block.BlockRoot, + block.ParentBlock, + block.Eth1DataBlockHash, + block.MhKey, + ) + } if err != nil { - loghelper.LogSlotError(dw.DbSlots.Slot, err).WithFields(log.Fields{"block_root": dw.DbSignedBeaconBlock.BlockRoot}).Error("Unable to write to the slot to the eth_beacon.signed_block table") + loghelper.LogSlotError(dw.DbSlots.Slot, err).WithFields(log.Fields{"block_root": block.BlockRoot}).Error("Unable to write to the slot to the eth_beacon.signed_block table") return err } return nil diff --git a/pkg/beaconclient/models.go b/pkg/beaconclient/models.go index 19f4d97..d9b40b3 100644 --- a/pkg/beaconclient/models.go +++ b/pkg/beaconclient/models.go @@ -60,21 +60,25 @@ type DbSlots struct { Status string // The status, it can be proposed | forked | skipped. } -// A struct to capture whats being written to eth-beacon.signed_block table. -type DbSignedBeaconBlock struct { - Slot string // The slot. - BlockRoot string // The block root - ParentBlock string // The parent block root. - Eth1DataBlockHash string // The eth1 block_hash - MhKey string // The ipld multihash key. - PayloadBlockNumber int64 - PayloadTimestamp int64 +type ExecutionPayloadSummary struct { + PayloadBlockNumber uint64 + PayloadTimestamp uint64 PayloadBlockHash string PayloadParentHash string PayloadStateRoot string PayloadReceiptsRoot string } +// A struct to capture whats being written to eth-beacon.signed_block table. +type DbSignedBeaconBlock struct { + Slot string // The slot. + BlockRoot string // The block root + ParentBlock string // The parent block root. + Eth1DataBlockHash string // The eth1 block_hash + MhKey string // The ipld multihash key. + ExecutionPayload *ExecutionPayloadSummary +} + // A struct to capture whats being written to eth-beacon.state table. type DbBeaconState struct { Slot string // The slot. diff --git a/pkg/beaconclient/processslot.go b/pkg/beaconclient/processslot.go index 35b000e..0bd2250 100644 --- a/pkg/beaconclient/processslot.go +++ b/pkg/beaconclient/processslot.go @@ -417,14 +417,17 @@ func (ps *ProcessSlot) createWriteObjects() (*DatabaseWriter, error) { } parseBeaconTime := time.Now() + // These will normally be pre-calculated by this point. blockRoot, stateRoot, eth1DataBlockHash, err := ps.provideFinalHash() if err != nil { return nil, err } ps.PerformanceMetrics.ParseBeaconObjectForHash = time.Since(parseBeaconTime) + payloadSummary := ps.provideExecutionPayloadDetails() + dw, err := CreateDatabaseWrite(ps.Db, ps.Slot, stateRoot, blockRoot, ps.ParentBlockRoot, eth1DataBlockHash, - status, &ps.SszSignedBeaconBlock, &ps.SszBeaconState, ps.Metrics) + payloadSummary, status, &ps.SszSignedBeaconBlock, &ps.SszBeaconState, ps.Metrics) if err != nil { return dw, err } @@ -474,6 +477,22 @@ func (ps *ProcessSlot) provideFinalHash() (string, string, string, error) { return blockRoot, stateRoot, eth1DataBlockHash, nil } +func (ps *ProcessSlot) provideExecutionPayloadDetails() *ExecutionPayloadSummary { + if nil == ps.FullSignedBeaconBlock || !ps.FullSignedBeaconBlock.IsBellatrix() { + return nil + } + + payload := ps.FullSignedBeaconBlock.bellatrix.Message.Body.ExecutionPayload + return &ExecutionPayloadSummary{ + PayloadBlockNumber: uint64(payload.BlockNumber), + PayloadTimestamp: uint64(payload.Timestamp), + PayloadBlockHash: toHex(payload.BlockHash), + PayloadParentHash: toHex(payload.ParentHash), + PayloadStateRoot: toHex(payload.StateRoot), + PayloadReceiptsRoot: toHex(payload.ReceiptsRoot), + } +} + func toHex(r [32]byte) string { return "0x" + hex.EncodeToString(r[:]) }