Skip to content

Commit ae78b9d

Browse files
authored
Merge pull request #148 from thirdweb-dev/02-04-column_selection_and_api_serialization
Specific column selection and api serialization
2 parents 34e38e0 + 2733e5c commit ae78b9d

File tree

11 files changed

+482
-278
lines changed

11 files changed

+482
-278
lines changed

internal/common/log.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,23 @@ type Log struct {
2121
LogIndex uint64 `json:"log_index" ch:"log_index"`
2222
Address string `json:"address" ch:"address"`
2323
Data string `json:"data" ch:"data"`
24-
Topics []string `json:"topics"`
24+
Topic0 string `json:"topic_0" ch:"topic_0"`
25+
Topic1 string `json:"topic_1" ch:"topic_1"`
26+
Topic2 string `json:"topic_2" ch:"topic_2"`
27+
Topic3 string `json:"topic_3" ch:"topic_3"`
28+
}
29+
30+
func (l *Log) GetTopic(index int) (string, error) {
31+
if index == 0 {
32+
return l.Topic0, nil
33+
} else if index == 1 {
34+
return l.Topic1, nil
35+
} else if index == 2 {
36+
return l.Topic2, nil
37+
} else if index == 3 {
38+
return l.Topic3, nil
39+
}
40+
return "", fmt.Errorf("invalid topic index: %d", index)
2541
}
2642

2743
type RawLogs = []map[string]interface{}
@@ -51,7 +67,7 @@ func DecodeLogs(chainId string, logs []Log) []*DecodedLog {
5167
return &decodedLog
5268
}
5369

54-
event, err := abi.EventByID(gethCommon.HexToHash(eventLog.Topics[0]))
70+
event, err := abi.EventByID(gethCommon.HexToHash(eventLog.Topic0))
5571
if err != nil {
5672
log.Debug().Msgf("failed to get method by id: %v", err)
5773
return &decodedLog
@@ -77,7 +93,6 @@ func DecodeLogs(chainId string, logs []Log) []*DecodedLog {
7793
}
7894

7995
func (l *Log) Decode(eventABI *abi.Event) *DecodedLog {
80-
8196
decodedIndexed := make(map[string]interface{})
8297
indexedArgs := abi.Arguments{}
8398
for _, arg := range eventABI.Inputs {
@@ -87,11 +102,12 @@ func (l *Log) Decode(eventABI *abi.Event) *DecodedLog {
87102
}
88103
// Decode indexed parameters
89104
for i, arg := range indexedArgs {
90-
if len(l.Topics) <= i+1 {
105+
topic, err := l.GetTopic(i + 1)
106+
if err != nil {
91107
log.Warn().Msgf("missing topic for indexed parameter: %s, signature: %s", arg.Name, eventABI.Sig)
92108
return &DecodedLog{Log: *l}
93109
}
94-
decodedValue, err := decodeIndexedArgument(arg.Type, l.Topics[i+1])
110+
decodedValue, err := decodeIndexedArgument(arg.Type, topic)
95111
if err != nil {
96112
log.Warn().Msgf("failed to decode indexed parameter %s: %v, signature: %s", arg.Name, err, eventABI.Sig)
97113
return &DecodedLog{Log: *l}

internal/common/log_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ import (
99
)
1010

1111
func TestDecodeLog(t *testing.T) {
12-
topics := make([]string, 3)
13-
topics[0] = "0x7be266734f0c132a415c32a35b76cbf3d8a02fa3d88628b286dcf713f53f1e2d"
14-
topics[1] = "0xc148159472ef0bbd3a304d3d3637b8deeda456572700669fda4f8d0fad814402"
15-
topics[2] = "0x000000000000000000000000ff0cb0351a356ad16987e5809a8daaaf34f5adbe"
1612
event := Log{
1713
Data: "0x000000000000000000000000000000000000000000000000b2da0f6658944b0600000000000000000000000000000000000000000000000000000000000000003492dc030870ae719a0babc07807601edd3fc7e150a6b4878d1c5571bd9995c00000000000000000000000000000000000000000000000e076c8d70085af000000000000000000000000000000000000000000000000000000469c6478f693140000000000000000000000000000000000000000000000000000000000000000",
18-
Topics: topics,
14+
Topic0: "0x7be266734f0c132a415c32a35b76cbf3d8a02fa3d88628b286dcf713f53f1e2d",
15+
Topic1: "0xc148159472ef0bbd3a304d3d3637b8deeda456572700669fda4f8d0fad814402",
16+
Topic2: "0x000000000000000000000000ff0cb0351a356ad16987e5809a8daaaf34f5adbe",
1917
}
2018

2119
eventABI, err := ConstructEventABI("LogCanonicalOrderFilled(bytes32 indexed orderHash,address indexed orderMaker,uint256 fillAmount,uint256 triggerPrice,bytes32 orderFlags,(uint256 price,uint128 fee,bool isNegativeFee) fill)")

internal/common/transaction.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type Transaction struct {
3131
R *big.Int `json:"r" ch:"r" swaggertype:"string"`
3232
S *big.Int `json:"s" ch:"s" swaggertype:"string"`
3333
V *big.Int `json:"v" ch:"v" swaggertype:"string"`
34-
AccessListJson *string `json:"access_list_json" ch:"access_list_json"`
34+
AccessListJson *string `json:"access_list_json" ch:"access_list"`
3535
ContractAddress *string `json:"contract_address" ch:"contract_address"`
3636
GasUsed *uint64 `json:"gas_used" ch:"gas_used"`
3737
CumulativeGasUsed *uint64 `json:"cumulative_gas_used" ch:"cumulative_gas_used"`

internal/handlers/blocks_handlers.go

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,34 @@ import (
44
"github.com/gin-gonic/gin"
55
"github.com/rs/zerolog/log"
66
"github.com/thirdweb-dev/indexer/api"
7+
"github.com/thirdweb-dev/indexer/internal/common"
78
"github.com/thirdweb-dev/indexer/internal/storage"
89
)
910

1011
// BlockModel represents a simplified Block structure for Swagger documentation
1112
type BlockModel struct {
12-
ChainId string `json:"chain_id"`
13-
Number string `json:"number"`
14-
Hash string `json:"hash"`
15-
ParentHash string `json:"parent_hash"`
16-
Timestamp uint64 `json:"timestamp"`
17-
Nonce string `json:"nonce"`
18-
Sha3Uncles string `json:"sha3_uncles"`
19-
LogsBloom string `json:"logs_bloom"`
20-
ReceiptsRoot string `json:"receipts_root"`
21-
Difficulty string `json:"difficulty"`
22-
TotalDifficulty string `json:"total_difficulty"`
23-
Size uint64 `json:"size"`
24-
ExtraData string `json:"extra_data"`
25-
GasLimit uint64 `json:"gas_limit"`
26-
GasUsed uint64 `json:"gas_used"`
27-
BaseFeePerGas string `json:"base_fee_per_gas"`
28-
WithdrawalsRoot string `json:"withdrawals_root"`
13+
ChainId string `json:"chain_id"`
14+
Number uint64 `json:"number"`
15+
Hash string `json:"hash"`
16+
ParentHash string `json:"parent_hash"`
17+
Timestamp uint64 `json:"timestamp"`
18+
Nonce string `json:"nonce"`
19+
Sha3Uncles string `json:"sha3_uncles"`
20+
MixHash string `json:"mix_hash"`
21+
Miner string `json:"miner"`
22+
StateRoot string `json:"state_root"`
23+
TransactionsRoot string `json:"transactions_root"`
24+
ReceiptsRoot string `json:"receipts_root"`
25+
LogsBloom string `json:"logs_bloom"`
26+
Size uint64 `json:"size"`
27+
ExtraData string `json:"extra_data"`
28+
Difficulty string `json:"difficulty"`
29+
TotalDifficulty string `json:"total_difficulty"`
30+
TransactionCount uint64 `json:"transaction_count"`
31+
GasLimit uint64 `json:"gas_limit"`
32+
GasUsed uint64 `json:"gas_used"`
33+
WithdrawalsRoot string `json:"withdrawals_root"`
34+
BaseFeePerGas uint64 `json:"base_fee_per_gas"`
2935
}
3036

3137
// @Summary Get all blocks
@@ -118,9 +124,40 @@ func handleBlocksRequest(c *gin.Context) {
118124
return
119125
}
120126

121-
queryResult.Data = blocksResult.Data
127+
queryResult.Data = serializeBlocks(blocksResult.Data)
122128
queryResult.Meta.TotalItems = len(blocksResult.Data)
123129
}
124130

125131
sendJSONResponse(c, queryResult)
126132
}
133+
134+
func serializeBlocks(blocks []common.Block) []BlockModel {
135+
blockModels := make([]BlockModel, len(blocks))
136+
for i, block := range blocks {
137+
blockModels[i] = BlockModel{
138+
ChainId: block.ChainId.String(),
139+
Number: block.Number.Uint64(),
140+
Hash: block.Hash,
141+
ParentHash: block.ParentHash,
142+
Timestamp: block.Timestamp,
143+
Nonce: block.Nonce,
144+
Sha3Uncles: block.Sha3Uncles,
145+
MixHash: block.MixHash,
146+
Miner: block.Miner,
147+
StateRoot: block.StateRoot,
148+
TransactionsRoot: block.TransactionsRoot,
149+
ReceiptsRoot: block.ReceiptsRoot,
150+
LogsBloom: block.LogsBloom,
151+
Size: block.Size,
152+
ExtraData: block.ExtraData,
153+
Difficulty: block.Difficulty.String(),
154+
TotalDifficulty: block.TotalDifficulty.String(),
155+
TransactionCount: block.TransactionCount,
156+
GasLimit: block.GasLimit.Uint64(),
157+
GasUsed: block.GasUsed.Uint64(),
158+
WithdrawalsRoot: block.WithdrawalsRoot,
159+
BaseFeePerGas: block.BaseFeePerGas,
160+
}
161+
}
162+
return blockModels
163+
}

internal/handlers/logs_handlers.go

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,28 @@ var (
2424
// LogModel represents a simplified Log structure for Swagger documentation
2525
type LogModel struct {
2626
ChainId string `json:"chain_id"`
27-
BlockNumber string `json:"block_number"`
27+
BlockNumber uint64 `json:"block_number"`
2828
BlockHash string `json:"block_hash"`
2929
BlockTimestamp uint64 `json:"block_timestamp"`
3030
TransactionHash string `json:"transaction_hash"`
3131
TransactionIndex uint64 `json:"transaction_index"`
3232
LogIndex uint64 `json:"log_index"`
3333
Address string `json:"address"`
3434
Data string `json:"data"`
35-
Topics []string `json:"topics"`
35+
Topics []string `json:"topics" swaggertype:"array,string"`
3636
}
3737

3838
type DecodedLogDataModel struct {
39-
Name string `json:"name"`
40-
Signature string `json:"signature"`
41-
Inputs map[string]interface{} `json:"inputs"`
39+
Name string `json:"name"`
40+
Signature string `json:"signature"`
41+
IndexedParams map[string]interface{} `json:"indexedParams" swaggertype:"object"`
42+
NonIndexedParams map[string]interface{} `json:"nonIndexedParams" swaggertype:"object"`
4243
}
4344

4445
type DecodedLogModel struct {
4546
LogModel
46-
Decoded DecodedLogDataModel `json:"decoded"`
47+
Decoded DecodedLogDataModel `json:"decoded"`
48+
DecodedData DecodedLogDataModel `json:"decodedData" deprecated:"true"` // Deprecated: Use Decoded field instead
4749
}
4850

4951
// @Summary Get all logs
@@ -202,18 +204,18 @@ func handleLogsRequest(c *gin.Context, contractAddress, signature string, eventA
202204
return
203205
}
204206
if eventABI != nil {
205-
decodedLogs := []*common.DecodedLog{}
207+
decodedLogs := []DecodedLogModel{}
206208
for _, log := range logsResult.Data {
207209
decodedLog := log.Decode(eventABI)
208-
decodedLogs = append(decodedLogs, decodedLog)
210+
decodedLogs = append(decodedLogs, serializeDecodedLog(*decodedLog))
209211
}
210212
queryResult.Data = decodedLogs
211213
} else {
212214
if config.Cfg.API.AbiDecodingEnabled && queryParams.Decode {
213215
decodedLogs := common.DecodeLogs(chainId.String(), logsResult.Data)
214-
queryResult.Data = decodedLogs
216+
queryResult.Data = serializeDecodedLogs(decodedLogs)
215217
} else {
216-
queryResult.Data = logsResult.Data
218+
queryResult.Data = serializeLogs(logsResult.Data)
217219
}
218220
}
219221
queryResult.Meta.TotalItems = len(logsResult.Data)
@@ -237,3 +239,59 @@ func getMainStorage() (storage.IMainStorage, error) {
237239
func sendJSONResponse(c *gin.Context, response interface{}) {
238240
c.JSON(http.StatusOK, response)
239241
}
242+
243+
func serializeDecodedLogs(logs []*common.DecodedLog) []DecodedLogModel {
244+
decodedLogModels := make([]DecodedLogModel, len(logs))
245+
for i, log := range logs {
246+
decodedLogModels[i] = serializeDecodedLog(*log)
247+
}
248+
return decodedLogModels
249+
}
250+
251+
func serializeDecodedLog(log common.DecodedLog) DecodedLogModel {
252+
decodedData := DecodedLogDataModel{
253+
Name: log.Decoded.Name,
254+
Signature: log.Decoded.Signature,
255+
IndexedParams: log.Decoded.IndexedParams,
256+
NonIndexedParams: log.Decoded.NonIndexedParams,
257+
}
258+
return DecodedLogModel{
259+
LogModel: serializeLog(log.Log),
260+
Decoded: decodedData,
261+
DecodedData: decodedData,
262+
}
263+
}
264+
265+
func serializeLogs(logs []common.Log) []LogModel {
266+
logModels := make([]LogModel, len(logs))
267+
for i, log := range logs {
268+
logModels[i] = serializeLog(log)
269+
}
270+
return logModels
271+
}
272+
273+
func serializeLog(log common.Log) LogModel {
274+
return LogModel{
275+
ChainId: log.ChainId.String(),
276+
BlockNumber: log.BlockNumber.Uint64(),
277+
BlockHash: log.BlockHash,
278+
BlockTimestamp: log.BlockTimestamp,
279+
TransactionHash: log.TransactionHash,
280+
TransactionIndex: log.TransactionIndex,
281+
LogIndex: log.LogIndex,
282+
Address: log.Address,
283+
Data: log.Data,
284+
Topics: serializeTopics(log),
285+
}
286+
}
287+
288+
func serializeTopics(log common.Log) []string {
289+
topics := []string{log.Topic0, log.Topic1, log.Topic2, log.Topic3}
290+
resultTopics := make([]string, 0, len(topics))
291+
for _, topic := range topics {
292+
if topic != "" {
293+
resultTopics = append(resultTopics, topic)
294+
}
295+
}
296+
return resultTopics
297+
}

0 commit comments

Comments
 (0)