github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/ledger/stmnt_from_traces.go (about) 1 package ledger 2 3 import ( 4 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 5 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" 6 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" 7 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 8 ) 9 10 func (l *Ledger) getStatementsFromTraces(conn *rpc.Connection, trans *types.Transaction, s *types.Statement) ([]types.Statement, error) { 11 statements := make([]types.Statement, 0, 20) // a high estimate of the number of statements we'll need 12 13 ret := *s 14 // clear all the internal accounting values. Keeps AmountIn, AmountOut and GasOut because 15 // those are at the top level (both the transaction itself and trace '0' have them). We 16 // skip trace '0' because it's the same as the transaction. 17 // ret.AmountIn.SetUint64(0) 18 ret.InternalIn.SetUint64(0) 19 ret.MinerBaseRewardIn.SetUint64(0) 20 ret.MinerNephewRewardIn.SetUint64(0) 21 ret.MinerTxFeeIn.SetUint64(0) 22 ret.MinerUncleRewardIn.SetUint64(0) 23 ret.CorrectingIn.SetUint64(0) 24 ret.PrefundIn.SetUint64(0) 25 ret.SelfDestructIn.SetUint64(0) 26 27 // ret.AmountOut.SetUint64(0) 28 // ret.GasOut.SetUint64(0) 29 ret.InternalOut.SetUint64(0) 30 ret.CorrectingOut.SetUint64(0) 31 ret.SelfDestructOut.SetUint64(0) 32 33 if traces, err := conn.GetTracesByTransactionHash(trans.Hash.Hex(), trans); err != nil { 34 return statements, err 35 36 } else { 37 // These values accumulate...so we use += instead of = 38 for i, trace := range traces { 39 if i == 0 { 40 // the first trace is identical to the transaction itself, so we can skip it 41 continue 42 } 43 if trace.Action.CallType == "delegatecall" && trace.Action.To != s.AccountedFor { 44 // delegate calls are not included in the transaction's gas cost, so we skip them 45 continue 46 } 47 48 plusEq := func(a1, a2 *base.Wei) base.Wei { 49 return *a1.Add(a1, a2) 50 } 51 52 // Do not collapse, more than one of these can be true at the same time 53 if trace.Action.From == s.AccountedFor { 54 ret.InternalOut = plusEq(&ret.InternalOut, &trace.Action.Value) 55 ret.Sender = trace.Action.From 56 if trace.Action.To.IsZero() { 57 if trace.Result != nil { 58 ret.Recipient = trace.Result.Address 59 } 60 } else { 61 ret.Recipient = trace.Action.To 62 } 63 } 64 65 if trace.Action.To == s.AccountedFor { 66 ret.InternalIn = plusEq(&ret.InternalIn, &trace.Action.Value) 67 ret.Sender = trace.Action.From 68 ret.Recipient = trace.Action.To 69 } 70 71 if trace.Action.SelfDestructed == s.AccountedFor { 72 ret.SelfDestructOut = plusEq(&ret.SelfDestructOut, &trace.Action.Balance) 73 ret.Sender = trace.Action.SelfDestructed 74 if ret.Sender.IsZero() { 75 ret.Sender = trace.Action.Address 76 } 77 ret.Recipient = trace.Action.RefundAddress 78 } 79 80 if trace.Action.RefundAddress == s.AccountedFor { 81 ret.SelfDestructIn = plusEq(&ret.SelfDestructIn, &trace.Action.Balance) 82 ret.Sender = trace.Action.SelfDestructed 83 if ret.Sender.IsZero() { 84 ret.Sender = trace.Action.Address 85 } 86 ret.Recipient = trace.Action.RefundAddress 87 } 88 89 if trace.Action.Address == s.AccountedFor && !trace.Action.RefundAddress.IsZero() { 90 ret.SelfDestructOut = plusEq(&ret.SelfDestructOut, &trace.Action.Balance) 91 // self destructed send 92 ret.Sender = trace.Action.Address 93 ret.Recipient = trace.Action.RefundAddress 94 } 95 96 if trace.Result != nil { 97 if trace.Result.Address == s.AccountedFor { 98 ret.InternalIn = plusEq(&ret.InternalIn, &trace.Action.Value) 99 ret.Sender = trace.Action.From 100 ret.Recipient = trace.Result.Address 101 } 102 } 103 } 104 } 105 106 if l.trialBalance("trace-eth", &ret) { 107 if ret.IsMaterial() { 108 statements = append(statements, ret) 109 } else { 110 logger.TestLog(true, "Tx reconciled with a zero value net amount. It's okay.") 111 } 112 } else { 113 // TODO: BOGUS PERF 114 // logger.Warn("Trace statement at", fmt.Sprintf("%d.%d", trans.BlockNumber, trans.TransactionIndex), " does not reconcile.") 115 statements = append(statements, ret) 116 } 117 118 return statements, nil 119 }