mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-12 06:53:46 +00:00
Ported back some fixes from Erigon extended native tracer
This commit is contained in:
parent
e51cbb0c95
commit
c36b44073f
1 changed files with 62 additions and 28 deletions
|
|
@ -123,12 +123,17 @@ func (f *Firehose) OnBlockStart(b *types.Block, td *big.Int, finalized *types.He
|
||||||
f.block = &pbeth.Block{
|
f.block = &pbeth.Block{
|
||||||
Hash: b.Hash().Bytes(),
|
Hash: b.Hash().Bytes(),
|
||||||
Number: b.Number().Uint64(),
|
Number: b.Number().Uint64(),
|
||||||
Header: newBlockHeaderFromChainBlock(b, firehoseBigIntFromNative(new(big.Int).Add(td, b.Difficulty()))),
|
Header: newBlockHeaderFromChainHeader(b.Header(), firehoseBigIntFromNative(new(big.Int).Add(td, b.Difficulty()))),
|
||||||
Size: b.Size(),
|
Size: b.Size(),
|
||||||
// Known Firehose issue: If you fix all known Firehose issue for a new chain, don't forget to bump `Ver` to `4`!
|
// Known Firehose issue: If you fix all known Firehose issue for a new chain, don't forget to bump `Ver` to `4`!
|
||||||
Ver: 3,
|
Ver: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, uncle := range b.Uncles() {
|
||||||
|
// TODO: check if td should be part of uncles
|
||||||
|
f.block.Uncles = append(f.block.Uncles, newBlockHeaderFromChainHeader(uncle, nil))
|
||||||
|
}
|
||||||
|
|
||||||
if f.block.Header.BaseFeePerGas != nil {
|
if f.block.Header.BaseFeePerGas != nil {
|
||||||
f.blockBaseFee = f.block.Header.BaseFeePerGas.Native()
|
f.blockBaseFee = f.block.Header.BaseFeePerGas.Native()
|
||||||
}
|
}
|
||||||
|
|
@ -197,8 +202,8 @@ func (f *Firehose) captureTxStart(tx *types.Transaction, hash common.Hash, from,
|
||||||
Value: firehoseBigIntFromNative(tx.Value()),
|
Value: firehoseBigIntFromNative(tx.Value()),
|
||||||
Input: tx.Data(),
|
Input: tx.Data(),
|
||||||
V: emptyBytesToNil(v.Bytes()),
|
V: emptyBytesToNil(v.Bytes()),
|
||||||
R: emptyBytesToNil(r.Bytes()),
|
R: normalizeSignaturePoint(r.Bytes()),
|
||||||
S: emptyBytesToNil(s.Bytes()),
|
S: normalizeSignaturePoint(s.Bytes()),
|
||||||
Type: transactionTypeFromChainTxType(tx.Type()),
|
Type: transactionTypeFromChainTxType(tx.Type()),
|
||||||
AccessList: newAccessListFromChain(tx.AccessList()),
|
AccessList: newAccessListFromChain(tx.AccessList()),
|
||||||
MaxFeePerGas: maxFeePerGas(tx),
|
MaxFeePerGas: maxFeePerGas(tx),
|
||||||
|
|
@ -250,7 +255,7 @@ func (f *Firehose) completeTransaction(receipt *types.Receipt) *pbeth.Transactio
|
||||||
// Order is important, we must populate the state reverted before we remove the log block index and re-assign ordinals
|
// Order is important, we must populate the state reverted before we remove the log block index and re-assign ordinals
|
||||||
f.populateStateReverted()
|
f.populateStateReverted()
|
||||||
f.removeLogBlockIndexOnStateRevertedCalls()
|
f.removeLogBlockIndexOnStateRevertedCalls()
|
||||||
f.assignOrdinalToReceiptLogs()
|
f.assignOrdinalAndIndexToReceiptLogs()
|
||||||
|
|
||||||
// Known Firehose issue: This field has never been populated in the old Firehose instrumentation, so it's the same thing for now
|
// Known Firehose issue: This field has never been populated in the old Firehose instrumentation, so it's the same thing for now
|
||||||
// f.transaction.ReturnData = rootCall.ReturnData
|
// f.transaction.ReturnData = rootCall.ReturnData
|
||||||
|
|
@ -292,7 +297,7 @@ func (f *Firehose) removeLogBlockIndexOnStateRevertedCalls() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Firehose) assignOrdinalToReceiptLogs() {
|
func (f *Firehose) assignOrdinalAndIndexToReceiptLogs() {
|
||||||
trx := f.transaction
|
trx := f.transaction
|
||||||
|
|
||||||
receiptsLogs := trx.Receipt.Logs
|
receiptsLogs := trx.Receipt.Logs
|
||||||
|
|
@ -325,7 +330,6 @@ func (f *Firehose) assignOrdinalToReceiptLogs() {
|
||||||
result := &validationResult{}
|
result := &validationResult{}
|
||||||
// Ordinal must **not** be checked as we are assigning it here below after the validations
|
// Ordinal must **not** be checked as we are assigning it here below after the validations
|
||||||
validateBytesField(result, "Address", callLog.Address, receiptsLog.Address)
|
validateBytesField(result, "Address", callLog.Address, receiptsLog.Address)
|
||||||
validateUint32Field(result, "Index", callLog.Index, receiptsLog.Index)
|
|
||||||
validateUint32Field(result, "BlockIndex", callLog.BlockIndex, receiptsLog.BlockIndex)
|
validateUint32Field(result, "BlockIndex", callLog.BlockIndex, receiptsLog.BlockIndex)
|
||||||
validateBytesField(result, "Data", callLog.Data, receiptsLog.Data)
|
validateBytesField(result, "Data", callLog.Data, receiptsLog.Data)
|
||||||
validateArrayOfBytesField(result, "Topics", callLog.Topics, receiptsLog.Topics)
|
validateArrayOfBytesField(result, "Topics", callLog.Topics, receiptsLog.Topics)
|
||||||
|
|
@ -334,6 +338,7 @@ func (f *Firehose) assignOrdinalToReceiptLogs() {
|
||||||
result.panicOnAnyFailures("mismatch between Firehose call log and Ethereum transaction receipt log at index %d", i)
|
result.panicOnAnyFailures("mismatch between Firehose call log and Ethereum transaction receipt log at index %d", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
receiptsLog.Index = callLog.Index
|
||||||
receiptsLog.Ordinal = callLog.Ordinal
|
receiptsLog.Ordinal = callLog.Ordinal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -442,6 +447,12 @@ func (f *Firehose) callStart(source string, callType pbeth.CallType, from common
|
||||||
input = nil
|
input = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := firehoseBigIntFromNative(value)
|
||||||
|
if callType == pbeth.CallType_DELEGATE {
|
||||||
|
// If it's a delegate call, the there should be a call in the stack and value should be parent's value
|
||||||
|
v = f.callStack.Peek().Value
|
||||||
|
}
|
||||||
|
|
||||||
call := &pbeth.Call{
|
call := &pbeth.Call{
|
||||||
// Known Firehose issue: Ref 042a2ff03fd623f151d7726314b8aad6 (see below)
|
// Known Firehose issue: Ref 042a2ff03fd623f151d7726314b8aad6 (see below)
|
||||||
//
|
//
|
||||||
|
|
@ -453,7 +464,7 @@ func (f *Firehose) callStart(source string, callType pbeth.CallType, from common
|
||||||
Address: to.Bytes(),
|
Address: to.Bytes(),
|
||||||
// We need to clone `input` received by the tracer as it's re-used within Geth!
|
// We need to clone `input` received by the tracer as it's re-used within Geth!
|
||||||
Input: bytes.Clone(input),
|
Input: bytes.Clone(input),
|
||||||
Value: firehoseBigIntFromNative(value),
|
Value: v,
|
||||||
GasLimit: gas,
|
GasLimit: gas,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -516,7 +527,7 @@ func (f *Firehose) callEnd(source string, output []byte, gasUsed uint64, err err
|
||||||
// call.ExecutedCode = true
|
// call.ExecutedCode = true
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// At this point, `call.ExecutedCode`` is tied to `EVMInterpreter#Run` execution (in `core/vm/interpreter.go`)
|
// At this point, `call.ExecutedCode` is tied to `EVMInterpreter#Run` execution (in `core/vm/interpreter.go`)
|
||||||
// and is `true` if the run/loop of the interpreter executed.
|
// and is `true` if the run/loop of the interpreter executed.
|
||||||
//
|
//
|
||||||
// This means that if `false` the interpreter did not run at all and we would had emitted a
|
// This means that if `false` the interpreter did not run at all and we would had emitted a
|
||||||
|
|
@ -954,33 +965,39 @@ func flushToFirehose(in []byte, writer io.Writer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Create a unit test that is going to fail as soon as any header is added in
|
// FIXME: Create a unit test that is going to fail as soon as any header is added in
|
||||||
func newBlockHeaderFromChainBlock(b *types.Block, td *pbeth.BigInt) *pbeth.BlockHeader {
|
func newBlockHeaderFromChainHeader(h *types.Header, td *pbeth.BigInt) *pbeth.BlockHeader {
|
||||||
var withdrawalsHashBytes []byte
|
var withdrawalsHashBytes []byte
|
||||||
if hash := b.Header().WithdrawalsHash; hash != nil {
|
if hash := h.WithdrawalsHash; hash != nil {
|
||||||
withdrawalsHashBytes = hash.Bytes()
|
withdrawalsHashBytes = hash.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pbeth.BlockHeader{
|
pbHead := &pbeth.BlockHeader{
|
||||||
Hash: b.Hash().Bytes(),
|
Hash: h.Hash().Bytes(),
|
||||||
Number: b.NumberU64(),
|
Number: h.Number.Uint64(),
|
||||||
ParentHash: b.ParentHash().Bytes(),
|
ParentHash: h.ParentHash.Bytes(),
|
||||||
UncleHash: b.UncleHash().Bytes(),
|
UncleHash: h.UncleHash.Bytes(),
|
||||||
Coinbase: b.Coinbase().Bytes(),
|
Coinbase: h.Coinbase.Bytes(),
|
||||||
StateRoot: b.Root().Bytes(),
|
StateRoot: h.Root.Bytes(),
|
||||||
TransactionsRoot: b.TxHash().Bytes(),
|
TransactionsRoot: h.TxHash.Bytes(),
|
||||||
ReceiptRoot: b.ReceiptHash().Bytes(),
|
ReceiptRoot: h.ReceiptHash.Bytes(),
|
||||||
LogsBloom: b.Bloom().Bytes(),
|
LogsBloom: h.Bloom.Bytes(),
|
||||||
Difficulty: firehoseBigIntFromNative(b.Difficulty()),
|
Difficulty: firehoseBigIntFromNative(h.Difficulty),
|
||||||
TotalDifficulty: td,
|
TotalDifficulty: td,
|
||||||
GasLimit: b.GasLimit(),
|
GasLimit: h.GasLimit,
|
||||||
GasUsed: b.GasUsed(),
|
GasUsed: h.GasUsed,
|
||||||
Timestamp: timestamppb.New(time.Unix(int64(b.Time()), 0)),
|
Timestamp: timestamppb.New(time.Unix(int64(h.Time), 0)),
|
||||||
ExtraData: b.Extra(),
|
ExtraData: h.Extra,
|
||||||
MixHash: b.MixDigest().Bytes(),
|
MixHash: h.MixDigest.Bytes(),
|
||||||
Nonce: b.Nonce(),
|
Nonce: h.Nonce.Uint64(),
|
||||||
BaseFeePerGas: firehoseBigIntFromNative(b.BaseFee()),
|
BaseFeePerGas: firehoseBigIntFromNative(h.BaseFee),
|
||||||
WithdrawalsRoot: withdrawalsHashBytes,
|
WithdrawalsRoot: withdrawalsHashBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pbHead.Difficulty == nil {
|
||||||
|
pbHead.Difficulty = &pbeth.BigInt{Bytes: []byte{0}}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pbHead
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Bring back Firehose test that ensures no new tx type are missed
|
// FIXME: Bring back Firehose test that ensures no new tx type are missed
|
||||||
|
|
@ -1443,6 +1460,23 @@ func emptyBytesToNil(in []byte) []byte {
|
||||||
return in
|
return in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizeSignaturePoint(value []byte) []byte {
|
||||||
|
if len(value) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(value) < 32 {
|
||||||
|
offset := 32 - len(value)
|
||||||
|
|
||||||
|
out := make([]byte, 32)
|
||||||
|
copy(out[offset:32], value)
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
return value[0:32]
|
||||||
|
}
|
||||||
|
|
||||||
func firehoseBigIntFromNative(in *big.Int) *pbeth.BigInt {
|
func firehoseBigIntFromNative(in *big.Int) *pbeth.BigInt {
|
||||||
if in == nil || in.Sign() == 0 {
|
if in == nil || in.Sign() == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue