Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: firehose live tracer #53

Draft
wants to merge 33 commits into
base: feature/erigon-live-tracer-port
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ae0e05e
firehose tracer added
dhyaniarun1993 Oct 30, 2023
efa194d
fix bugs
dhyaniarun1993 Nov 2, 2023
cecd3b4
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Nov 2, 2023
bdf5917
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Nov 6, 2023
889f8be
feature/erigon-live-tracer-port merged
dhyaniarun1993 Nov 6, 2023
3029efe
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Nov 6, 2023
73931ad
refactor
dhyaniarun1993 Nov 6, 2023
6766b46
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Nov 7, 2023
dfcc4d0
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Nov 28, 2023
983a37e
bugfixes
dhyaniarun1993 Nov 28, 2023
c55a05e
code refactor
dhyaniarun1993 Dec 6, 2023
c06028c
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Dec 11, 2023
ad989aa
account creation backward compatibility
dhyaniarun1993 Dec 12, 2023
be910c9
executed code corner case
dhyaniarun1993 Dec 12, 2023
fa85b27
topic backward compatibility fix
dhyaniarun1993 Dec 13, 2023
1251baf
revert: topic backward compatibility fix
dhyaniarun1993 Dec 13, 2023
4bb66cd
feature/erigon-live-tracer-port merged
dhyaniarun1993 Jan 10, 2024
ff0e93a
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Jan 11, 2024
88715da
remove delegate value hack
dhyaniarun1993 Jan 11, 2024
d37c193
fix comment
dhyaniarun1993 Feb 12, 2024
5a3c874
erigon tracer merged and conflict resolved
dhyaniarun1993 Feb 13, 2024
2741e7e
Updated when FIRE INIT is actually printed
dhyaniarun1993 Feb 13, 2024
36d5bf0
feature/erigon-live-tracer-port merged
dhyaniarun1993 Feb 16, 2024
9705550
merge code fixes
dhyaniarun1993 Feb 16, 2024
6bbe0a3
Reduce amount of changes to Geth Live Tracer to keep Firehose backwar…
dhyaniarun1993 Feb 16, 2024
9133014
added firehose pb
dhyaniarun1993 Feb 18, 2024
d110d39
revert back to streaming fast pb
dhyaniarun1993 Feb 19, 2024
fb7018e
revert back to streaming fast pb
dhyaniarun1993 Feb 19, 2024
b46f0fd
fire init bugfixes
dhyaniarun1993 Feb 19, 2024
15bf7e1
firehose printer bugfix
dhyaniarun1993 Feb 19, 2024
ac60358
bugfix
dhyaniarun1993 Feb 19, 2024
aa68ce4
ignore BalanceDecreaseSelfdestructBurn
dhyaniarun1993 Feb 20, 2024
22ee5a7
Merge branch 'feature/erigon-live-tracer-port' into feat/firehose-liv…
dhyaniarun1993 Feb 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion consensus/aura/aura.go
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ func (c *AuRa) applyRewards(header *types.Header, state *state.IntraBlockState,
return err
}
for _, r := range rewards {
state.AddBalance(r.Beneficiary, &r.Amount, evmtypes.BalanceChangeRewardMineBlock)
state.AddBalance(r.Beneficiary, &r.Amount, false, evmtypes.BalanceChangeRewardMineBlock)
}
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,8 +666,8 @@ func accumulateRewards(config *chain.Config, state *state.IntraBlockState, heade
minerReward, uncleRewards := AccumulateRewards(config, header, uncles)
for i, uncle := range uncles {
if i < len(uncleRewards) {
state.AddBalance(uncle.Coinbase, &uncleRewards[i], evmtypes.BalanceChangeRewardMineUncle)
state.AddBalance(uncle.Coinbase, &uncleRewards[i], false, evmtypes.BalanceChangeRewardMineUncle)
}
}
state.AddBalance(header.Coinbase, &minerReward, evmtypes.BalanceChangeRewardMineBlock)
state.AddBalance(header.Coinbase, &minerReward, false, evmtypes.BalanceChangeRewardMineBlock)
}
8 changes: 4 additions & 4 deletions consensus/merge/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *stat
for _, r := range rewards {
switch r.Kind {
case consensus.RewardAuthor:
state.AddBalance(r.Beneficiary, &r.Amount, evmtypes.BalanceChangeRewardMineBlock)
state.AddBalance(r.Beneficiary, &r.Amount, false, evmtypes.BalanceChangeRewardMineBlock)
case consensus.RewardUncle:
state.AddBalance(r.Beneficiary, &r.Amount, evmtypes.BalanceChangeRewardMineUncle)
state.AddBalance(r.Beneficiary, &r.Amount, false, evmtypes.BalanceChangeRewardMineUncle)
default:
state.AddBalance(r.Beneficiary, &r.Amount, evmtypes.BalanceChangeUnspecified)
state.AddBalance(r.Beneficiary, &r.Amount, false, evmtypes.BalanceChangeUnspecified)
}
}

Expand All @@ -162,7 +162,7 @@ func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *stat
} else {
for _, w := range withdrawals {
amountInWei := new(uint256.Int).Mul(uint256.NewInt(w.Amount), uint256.NewInt(params.GWei))
state.AddBalance(w.Address, amountInWei, evmtypes.BalanceChangeWithdrawal)
state.AddBalance(w.Address, amountInWei, false, evmtypes.BalanceChangeWithdrawal)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion consensus/misc/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func ApplyDAOHardFork(statedb *state.IntraBlockState) {

// Move every DAO account and extra-balance account funds into the refund contract
for _, addr := range params.DAODrainList() {
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), evmtypes.BalanceChangeDaoRefundContract)
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), false, evmtypes.BalanceChangeDaoRefundContract)
statedb.SetBalance(addr, new(uint256.Int), evmtypes.BalanceChangeDaoAdjustBalance)
}
}
4 changes: 2 additions & 2 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func Transfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address,
if !bailout {
db.SubBalance(sender, amount, evmtypes.BalanceChangeTransfer)
}
db.AddBalance(recipient, amount, evmtypes.BalanceChangeTransfer)
db.AddBalance(recipient, amount, false, evmtypes.BalanceChangeTransfer)
}

// BorTransfer transfer in Bor
Expand All @@ -141,7 +141,7 @@ func BorTransfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Addres
if !bailout {
db.SubBalance(sender, amount, evmtypes.BalanceChangeTransfer)
}
db.AddBalance(recipient, amount, evmtypes.BalanceChangeTransfer)
db.AddBalance(recipient, amount, false, evmtypes.BalanceChangeTransfer)

// get outputs after
output1 := db.GetBalance(sender).Clone()
Expand Down
2 changes: 1 addition & 1 deletion core/genesis_write.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ func GenesisToBlock(g *types.Genesis, tmpDir string, bcLogger BlockchainLogger)
}
// This is not actually logged via tracer because OnGenesisBlock
// already captures the allocations.
statedb.AddBalance(addr, balance, evmtypes.BalanceChangeGenesisBalance)
statedb.AddBalance(addr, balance, false, evmtypes.BalanceChangeGenesisBalance)
statedb.SetCode(addr, account.Code)
statedb.SetNonce(addr, account.Nonce)
for key, value := range account.Storage {
Expand Down
8 changes: 4 additions & 4 deletions core/state/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ func TestReproduceCrash(t *testing.T) {
t.Errorf("error finalising 1st tx: %v", err)
}
// Start the 3rd transaction
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), 0x0)
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), false, 0x0)
intraBlockState.SetState(contract, &storageKey2, *value2)
if err := intraBlockState.FinalizeTx(&chain.Rules{}, tsw); err != nil {
t.Errorf("error finalising 1st tx: %v", err)
Expand Down Expand Up @@ -1232,7 +1232,7 @@ func TestChangeAccountCodeBetweenBlocks(t *testing.T) {
oldCode := []byte{0x01, 0x02, 0x03, 0x04}

intraBlockState.SetCode(contract, oldCode)
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), 0x0)
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), false, 0x0)
if err := intraBlockState.FinalizeTx(&chain.Rules{}, tsw); err != nil {
t.Errorf("error finalising 1st tx: %v", err)
}
Expand Down Expand Up @@ -1270,7 +1270,7 @@ func TestCacheCodeSizeSeparately(t *testing.T) {
code := []byte{0x01, 0x02, 0x03, 0x04}

intraBlockState.SetCode(contract, code)
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), 0x0)
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), false, 0x0)
if err := intraBlockState.FinalizeTx(&chain.Rules{}, w); err != nil {
t.Errorf("error finalising 1st tx: %v", err)
}
Expand Down Expand Up @@ -1303,7 +1303,7 @@ func TestCacheCodeSizeInTrie(t *testing.T) {
code := []byte{0x01, 0x02, 0x03, 0x04}

intraBlockState.SetCode(contract, code)
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), 0x0)
intraBlockState.AddBalance(contract, uint256.NewInt(1000000000), false, 0x0)
if err := intraBlockState.FinalizeTx(&chain.Rules{}, w); err != nil {
t.Errorf("error finalising 1st tx: %v", err)
}
Expand Down
25 changes: 17 additions & 8 deletions core/state/intra_block_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) bool {

// AddBalance adds amount to the account associated with addr.
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.Int, reason evmtypes.BalanceChangeReason) {
func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.Int, checkPrecompile bool, reason evmtypes.BalanceChangeReason) {
if sdb.trace {
fmt.Printf("AddBalance %x, %d\n", addr, amount)
}
Expand All @@ -356,7 +356,7 @@ func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.I
}
}

stateObject := sdb.GetOrNewStateObject(addr)
stateObject := sdb.getOrNewStateObject(addr, checkPrecompile)
stateObject.AddBalance(amount, reason)
}

Expand Down Expand Up @@ -509,7 +509,7 @@ func (sdb *IntraBlockState) getStateObject(addr libcommon.Address) (stateObject
// Load the object from the database.
if _, ok := sdb.nilAccounts[addr]; ok {
if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred {
return sdb.createObject(addr, nil)
return sdb.createObject(addr, nil, false)
}
return nil
}
Expand All @@ -521,7 +521,7 @@ func (sdb *IntraBlockState) getStateObject(addr libcommon.Address) (stateObject
if account == nil {
sdb.nilAccounts[addr] = struct{}{}
if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred {
return sdb.createObject(addr, nil)
return sdb.createObject(addr, nil, false)
}
return nil
}
Expand All @@ -543,16 +543,20 @@ func (sdb *IntraBlockState) setStateObject(addr libcommon.Address, object *state

// Retrieve a state object or create a new state object if nil.
func (sdb *IntraBlockState) GetOrNewStateObject(addr libcommon.Address) *stateObject {
return sdb.getOrNewStateObject(addr, false)
}

func (sdb *IntraBlockState) getOrNewStateObject(addr libcommon.Address, checkPrecompile bool) *stateObject {
stateObject := sdb.getStateObject(addr)
if stateObject == nil || stateObject.deleted {
stateObject = sdb.createObject(addr, stateObject /* previous */)
stateObject = sdb.createObject(addr, stateObject /* previous */, checkPrecompile)
}
return stateObject
}

// createObject creates a new state object. If there is an existing account with
// the given address, it is overwritten.
func (sdb *IntraBlockState) createObject(addr libcommon.Address, previous *stateObject) (newobj *stateObject) {
func (sdb *IntraBlockState) createObject(addr libcommon.Address, previous *stateObject, checkPrecompile bool) (newobj *stateObject) {
account := new(accounts.Account)
var original *accounts.Account
if previous == nil {
Expand All @@ -572,7 +576,12 @@ func (sdb *IntraBlockState) createObject(addr libcommon.Address, previous *state
if sdb.logger != nil {
// Precompiled contracts are touched during a call.
// Make sure we avoid emitting a new account event for them.
if _, ok := sdb.precompiles[addr]; !ok {
// checkPrecompile is added to make the tracer backward compatible with old firehose merged blocks
if checkPrecompile {
if _, ok := sdb.precompiles[addr]; !ok {
sdb.logger.OnNewAccount(addr)
}
} else {
sdb.logger.OnNewAccount(addr)
}
}
Expand Down Expand Up @@ -607,7 +616,7 @@ func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreati
}
}

newObj := sdb.createObject(addr, previous)
newObj := sdb.createObject(addr, previous, false)
if previous != nil && !previous.selfdestructed {
newObj.data.Balance.Set(&previous.data.Balance)
}
Expand Down
2 changes: 1 addition & 1 deletion core/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (s *StateSuite) TestTouchDelete(c *checker.C) {
s.state.Reset()

snapshot := s.state.Snapshot()
s.state.AddBalance(common.Address{}, new(uint256.Int), 0x0)
s.state.AddBalance(common.Address{}, new(uint256.Int), false, 0x0)

if len(s.state.journal.dirties) != 1 {
c.Fatal("expected one dirty state object")
Expand Down
6 changes: 3 additions & 3 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,12 +441,12 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
}
amount := new(uint256.Int).SetUint64(st.gasUsed())
amount.Mul(amount, effectiveTip) // gasUsed * effectiveTip = how much goes to the block producer (miner, validator)
st.state.AddBalance(coinbase, amount, evmtypes.BalanceChangeRewardTransactionFee)
st.state.AddBalance(coinbase, amount, false, evmtypes.BalanceChangeRewardTransactionFee)
if !msg.IsFree() && rules.IsLondon {
burntContractAddress := st.evm.ChainConfig().GetBurntContract(st.evm.Context().BlockNumber)
if burntContractAddress != nil {
burnAmount := new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gasUsed()), st.evm.Context().BaseFee)
st.state.AddBalance(*burntContractAddress, burnAmount, evmtypes.BalanceChangeBurn)
st.state.AddBalance(*burntContractAddress, burnAmount, false, evmtypes.BalanceChangeBurn)
}
}
if st.isBor {
Expand Down Expand Up @@ -489,7 +489,7 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {

// Return ETH for remaining gas, exchanged at the original rate.
remaining := new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gas), st.gasPrice)
st.state.AddBalance(st.msg.From(), remaining, evmtypes.BalanceChangeGasRefund)
st.state.AddBalance(st.msg.From(), remaining, false, evmtypes.BalanceChangeGasRefund)

if st.evm.Config().Tracer != nil && st.gas > 0 {
st.evm.Config().Tracer.OnGasChange(st.gas, 0, vm.GasChangeTxLeftOverReturned)
Expand Down
2 changes: 1 addition & 1 deletion core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,
// but is the correct thing to do and matters on other networks, in tests, and potential
// future scenarios
evm.intraBlockState.AddBalance(addr, u256.Num0, evmtypes.BalanceChangeTouchAccount)
evm.intraBlockState.AddBalance(addr, u256.Num0, true, evmtypes.BalanceChangeTouchAccount)
}

// It is allowed to call precompiles, even via delegatecall
Expand Down
2 changes: 1 addition & 1 deletion core/vm/evmtypes/evmtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ type IntraBlockState interface {
CreateAccount(common.Address, bool)

SubBalance(common.Address, *uint256.Int, BalanceChangeReason)
AddBalance(common.Address, *uint256.Int, BalanceChangeReason)
AddBalance(common.Address, *uint256.Int, bool, BalanceChangeReason)
GetBalance(common.Address) *uint256.Int

GetNonce(common.Address) uint64
Expand Down
4 changes: 2 additions & 2 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
callerAddr := scope.Contract.Address()
beneficiaryAddr := libcommon.Address(beneficiary.Bytes20())
balance := *interpreter.evm.IntraBlockState().GetBalance(callerAddr)
interpreter.evm.IntraBlockState().AddBalance(beneficiaryAddr, &balance, evmtypes.BalanceChangeSuicideRefund)
interpreter.evm.IntraBlockState().AddBalance(beneficiaryAddr, &balance, false, evmtypes.BalanceChangeSuicideRefund)
interpreter.evm.IntraBlockState().Selfdestruct(callerAddr)
if interpreter.evm.Config().Tracer != nil {
interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, callerAddr, beneficiaryAddr, false /* precompile */, false /* create */, []byte{}, 0, &balance, nil /* code */)
Expand All @@ -920,7 +920,7 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon
beneficiaryAddr := libcommon.Address(beneficiary.Bytes20())
balance := *interpreter.evm.IntraBlockState().GetBalance(callerAddr)
interpreter.evm.IntraBlockState().SubBalance(callerAddr, &balance, evmtypes.BalanceChangeSuicideWithdraw)
interpreter.evm.IntraBlockState().AddBalance(beneficiaryAddr, &balance, evmtypes.BalanceChangeSuicideRefund)
interpreter.evm.IntraBlockState().AddBalance(beneficiaryAddr, &balance, false, evmtypes.BalanceChangeSuicideRefund)
interpreter.evm.IntraBlockState().Selfdestruct6780(callerAddr)
if interpreter.evm.Config().Tracer != nil {
interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, callerAddr, beneficiaryAddr, false /* precompile */, false /* create */, []byte{}, 0, &balance, nil /* code */)
Expand Down
4 changes: 0 additions & 4 deletions eth/tracers/live/firehose.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,10 +825,6 @@ func (f *Firehose) OnNewAccount(a libcommon.Address) {
return
}

if f.isPrecompileAddress(a) {
return
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this method is not working but propagating the precompile down to StateDB works. I think it will be important to understand what is the difference.

That being said, the native tracer Git commit s1na/go-ethereum@ee58cc7 implements it differently, I think porting those will be needed

Copy link
Collaborator Author

@dhyaniarun1993 dhyaniarun1993 Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That being said, the native tracer Git commit s1na/go-ethereum@ee58cc7 implements it differently, I think porting those will be needed

These changes are already ported in statedb: precompile check before onNewAccount commit. I removed precompile check from here since it being done at statedb now.

How this method is not working but propagating the precompile down to StateDB works. I think it will be important to understand what is the difference.

In the old firehose implementation, we take the precompile flag on the AddBalance here. If you check the references of AddBalance, In majority of the cases we are sending hardcoded false instead of checking against the precompile config. Because of this even precompiled contracts are getting logged in the NewAccount in some cases.
Whereas in new implementation, each and every account was checked against the precompile config.

In this commit, I added a new flag checkPrecompile, that denotes if new account should be checked against precompiled address or not. I am sending checkPrecompile values according to the firehose old implementation to make the new tracer backward compatible.

@maoueh Let me know what you think

accountCreation := &pbeth.AccountCreation{
Account: a.Bytes(),
Ordinal: f.blockOrdinal.Next(),
Expand Down