github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/rpc/get_traces.go (about) 1 // Copyright 2021 The TrueBlocks Authors. All rights reserved. 2 // Use of this source code is governed by a license that can 3 // be found in the LICENSE file. 4 5 package rpc 6 7 import ( 8 "fmt" 9 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc/query" 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 13 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk" 14 ) 15 16 // GetTracesByBlockNumber returns a slice of traces in the given block 17 func (conn *Connection) GetTracesByBlockNumber(bn base.Blknum) ([]types.Trace, error) { 18 if conn.StoreReadable() { 19 // walk.Cache_Traces 20 traceGroup := &types.TraceGroup{ 21 BlockNumber: bn, 22 TransactionIndex: base.NOPOSN, // no tx id means we're storing the whole block 23 } 24 if err := conn.Store.Read(traceGroup, nil); err == nil { 25 return traceGroup.Traces, nil 26 } 27 } 28 29 curTs := conn.GetBlockTimestamp(bn) // same for every trace 30 isFinal := base.IsFinal(conn.LatestBlockTimestamp, curTs) 31 32 method := "trace_block" 33 params := query.Params{fmt.Sprintf("0x%x", bn)} 34 35 if traces, err := query.Query[[]types.Trace](conn.Chain, method, params); err != nil { 36 return []types.Trace{{ 37 Action: &types.TraceAction{}, 38 Result: &types.TraceResult{}, 39 }}, err 40 41 } else if traces == nil || len(*traces) == 0 { 42 return []types.Trace{{ 43 Action: &types.TraceAction{}, 44 Result: &types.TraceResult{}, 45 }}, err 46 47 } else { 48 curTx := base.NOPOSN 49 50 var traceIndex base.Tracenum 51 for i := range *traces { 52 traces := &(*traces)[i] 53 traces.Timestamp = curTs 54 if traces.Result == nil { 55 traces.Result = &types.TraceResult{} 56 } 57 traces.TransactionIndex = traces.TransactionPosition 58 if traces.TransactionIndex != base.Txnum(curTx) { 59 curTx = traces.TransactionIndex 60 traceIndex = 0 61 } 62 traces.TraceIndex = traceIndex 63 traceIndex++ 64 } 65 66 if isFinal && conn.StoreWritable() && conn.EnabledMap[walk.Cache_Traces] { 67 traceGroup := &types.TraceGroup{ 68 Traces: *traces, 69 BlockNumber: bn, 70 TransactionIndex: base.NOPOSN, 71 } 72 _ = conn.Store.Write(traceGroup, nil) 73 } 74 return *traces, nil 75 } 76 } 77 78 // GetTracesByTransactionHash returns a slice of traces in a given transaction's hash 79 func (conn *Connection) GetTracesByTransactionHash(txHash string, transaction *types.Transaction) ([]types.Trace, error) { 80 if conn.StoreReadable() && transaction != nil { 81 // walk.Cache_Traces 82 traceGroup := &types.TraceGroup{ 83 BlockNumber: transaction.BlockNumber, 84 TransactionIndex: transaction.TransactionIndex, 85 Traces: make([]types.Trace, 0, len(transaction.Traces)), 86 } 87 if err := conn.Store.Read(traceGroup, nil); err == nil { 88 return traceGroup.Traces, nil 89 } 90 } 91 92 method := "trace_transaction" 93 params := query.Params{txHash} 94 95 if traces, err := query.Query[[]types.Trace](conn.Chain, method, params); err != nil { 96 return []types.Trace{{ 97 Action: &types.TraceAction{}, 98 Result: &types.TraceResult{}, 99 }}, err 100 101 } else if traces == nil || len(*traces) == 0 { 102 return []types.Trace{{ 103 Action: &types.TraceAction{}, 104 Result: &types.TraceResult{}, 105 }}, err 106 107 } else { 108 curApp := types.Appearance{BlockNumber: uint32(^uint32(0))} 109 var traceIndex base.Tracenum 110 for i := range *traces { 111 traces := &(*traces)[i] 112 if transaction != nil { 113 traces.Timestamp = transaction.Timestamp 114 } 115 if traces.Result == nil { 116 traces.Result = &types.TraceResult{} 117 } 118 traces.TransactionIndex = traces.TransactionPosition 119 if traces.BlockNumber != base.Blknum(curApp.BlockNumber) || traces.TransactionIndex != base.Txnum(curApp.TransactionIndex) { 120 curApp = types.Appearance{ 121 BlockNumber: uint32(traces.BlockNumber), 122 TransactionIndex: uint32(traces.TransactionIndex), 123 } 124 traceIndex = 0 125 } 126 traces.TraceIndex = traceIndex 127 traceIndex++ 128 } 129 130 if transaction != nil { 131 isFinal := base.IsFinal(conn.LatestBlockTimestamp, transaction.Timestamp) 132 if isFinal && conn.StoreWritable() && conn.EnabledMap[walk.Cache_Traces] { 133 traceGroup := &types.TraceGroup{ 134 BlockNumber: transaction.BlockNumber, 135 TransactionIndex: transaction.TransactionIndex, 136 Traces: *traces, 137 } 138 _ = conn.Store.Write(traceGroup, nil) 139 } 140 } 141 142 return *traces, nil 143 } 144 }