Skip to content

Commit

Permalink
Merge pull request #181 from blocknative/TS_fix_value_transfer_on_revert
Browse files Browse the repository at this point in the history
fix: Don't count transfers that get reverted.
  • Loading branch information
tyler-smith authored Jul 15, 2024
2 parents 5c10b6b + 11f3185 commit 1b1a2e9
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 30 deletions.
17 changes: 7 additions & 10 deletions eth/tracers/blocknative/decoder/balances.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,18 @@ func newBalances() *balances {
}
}

// captureCallFrameStart decodes potential balance change data out of calldata.
func (bt *balances) captureCallFrameStart(sender common.Address, receiver common.Address, value *Amount, decoded *CallFrame) {
// Add the native transfer.
if value != nil && value.ToInt().Sign() > 0 {
bt.balanceChanges.addAssetTransfer(EthAsset, sender, receiver, value)
func (bt *balances) captureCallFrameEnd(cf *CallFrame) {
if cf == nil {
return
}
}

func (bt *balances) captureCallFrameEnd(decoded *CallFrame) {
if decoded == nil {
return
// Add the native transfer.
if cf.value != nil && cf.value.ToInt().Sign() > 0 {
bt.balanceChanges.addAssetTransfer(EthAsset, cf.sender, cf.receiver, cf.value)
}

// Add any decoded transfers.
for _, transfer := range decoded.Transfers {
for _, transfer := range cf.Transfers {
// Add the decoded transfer now.
bt.balanceChanges.addAssetTransfer(transfer.Asset, transfer.From, transfer.To, transfer.Value)
}
Expand Down
7 changes: 4 additions & 3 deletions eth/tracers/blocknative/decoder/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ func (d *Decoder) DecodeCallFrameStart(sender common.Address, receiver common.Ad
}
}

cf := &CallFrame{Contract: contract, CallData: callData}

d.balances.captureCallFrameStart(sender, receiver, NewAmount(value), cf)
cf := &CallFrame{Contract: contract, CallData: callData, sender: sender, receiver: receiver}
if value != nil {
cf.value = NewAmount(value)
}

return cf, nil
}
Expand Down
4 changes: 4 additions & 0 deletions eth/tracers/blocknative/decoder/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import (
type CallFrame struct {
*Contract
*CallData

sender common.Address
receiver common.Address
value *Amount
}

type Contract struct {
Expand Down
37 changes: 20 additions & 17 deletions eth/tracers/blocknative/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func (t *Tracer) onExit(depth int, output []byte, gasUsed uint64, err error, rev
return
}

t.captureExit(output, gasUsed, err)
t.captureExit(output, gasUsed, err, reverted)
}

// captureStart is called before the top-level call starts.
Expand Down Expand Up @@ -258,22 +258,23 @@ func (t *Tracer) captureEnter(typ vm.OpCode, from common.Address, to common.Addr
}

// captureEnd is called after the top-level call finishes to finalize tracing.
func (t *Tracer) captureEnd(output []byte, gasUsed uint64, err error, _ bool) {
if err := t.finalizeCallFrame(&t.callStack[0], output, gasUsed, err); err != nil {
func (t *Tracer) captureEnd(output []byte, gasUsed uint64, err error, reverted bool) {
if err := t.finalizeCallFrame(&t.callStack[0], output, gasUsed, err, reverted); err != nil {
log.Error("failed to finalize call frame", "err", err)
}

// Add gas payments to balance changes iff the tx succeeded.
if err == nil && t.opts.Decode {
if err == nil && !reverted && t.opts.Decode {
t.decoder.CaptureGas(t.origin, t.vmCtx.Coinbase, gasUsed, t.vmCtx.GasPrice, t.evm.Context.BaseFee)

}

// Add total time duration for this trace request
t.trace.Time = time.Since(t.startTime).Nanoseconds()
}

// captureExit is called after any sub call ends.
func (t *Tracer) captureExit(output []byte, gasUsed uint64, err error) {
func (t *Tracer) captureExit(output []byte, gasUsed uint64, err error, reverted bool) {
// Skip if we have no call-frames.
size := len(t.callStack)
if size == 0 {
Expand All @@ -282,7 +283,7 @@ func (t *Tracer) captureExit(output []byte, gasUsed uint64, err error) {

// We have a call-frame, so finalize it.
call := t.callStack[size-1]
if err := t.finalizeCallFrame(&call, output, gasUsed, err); err != nil {
if err := t.finalizeCallFrame(&call, output, gasUsed, err, reverted); err != nil {
log.Error("failed to finalize call frame", "err", err)
return
}
Expand All @@ -299,17 +300,8 @@ func (t *Tracer) captureExit(output []byte, gasUsed uint64, err error) {
t.callStack[end].Calls = append(t.callStack[end].Calls, call)
}

func (t *Tracer) finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) error {
call.GasUsed = Uint64(gasUsed)

// Finalize the decoding.
if t.opts.Decode && call.Decoded != nil {
if err := t.decoder.DecodeCallFrameEnd(call.Decoded); err != nil {
return err
}
}

// If there was an error then try decoding it and Stop.
func (t *Tracer) finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error, reverted bool) error {
// If there was an error or revert then handle it right away and then stop.
if err != nil {
call.Error = err.Error()
if err.Error() == "execution reverted" && len(output) > 0 {
Expand All @@ -324,6 +316,17 @@ func (t *Tracer) finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint6
return nil
}

if reverted {
return nil
}

// Finalize the decoding.
call.GasUsed = Uint64(gasUsed)
if t.opts.Decode && call.Decoded != nil {
if err := t.decoder.DecodeCallFrameEnd(call.Decoded); err != nil {
return err
}
}
call.Output = output
return nil
}
Expand Down

0 comments on commit 1b1a2e9

Please sign in to comment.