From 6346b75b65065161b9495ca2ec5dad7bf4fb2fd9 Mon Sep 17 00:00:00 2001 From: Ryan Smith Date: Wed, 1 Nov 2023 09:32:51 -0700 Subject: [PATCH] abi2: expose array index when decoding abi arrays (#191) E2PG copies N rows where N is equal to the number of elements in an abi encoded array(s). For example, if you have the following type: X(uint8,uint8[2]) then, assuming no filters, 2 rows will be inserted into the table. Each row will have the first uint8 and the 1 and 2nd row will have the 0th and 1st element of the abi encoded array respectively. This change allows the integration to request the array index be copied into the row. Continuing the example, given the following bytes: 000000000000000000000000000000000000000000000000000000000000002a 0000000000000000000000000000000000000000000000000000000000000040 0000000000000000000000000000000000000000000000000000000000000002 000000000000000000000000000000000000000000000000000000000000002b 000000000000000000000000000000000000000000000000000000000000002c the following rows will be inserted: abi_idx | a | b ---------+----+---- 0 | 42 | 43 1 | 42 | 44 E2PG decodes a log which contains an abi array, (eg an array of structs or an array of uint256s) --- abi2/abi2.go | 12 +++++++++--- e2pg/integration_test.go | 13 ++++++++----- e2pg/testdata/seaport.json | 6 ++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/abi2/abi2.go b/abi2/abi2.go index 4c487e48..75485986 100644 --- a/abi2/abi2.go +++ b/abi2/abi2.go @@ -775,9 +775,15 @@ func (ig Integration) processLog(rows [][]any, lwc *logWithCtx) ([][]any, error) row[j] = dbtype(def.Input.Type, d) ictr++ case !def.BlockData.Empty(): - d := lwc.get(def.BlockData.Name) - if b, ok := d.([]byte); ok && !def.BlockData.Accept(b) { - return rows, nil + var d any + switch { + case def.BlockData.Name == "abi_idx": + d = i + default: + d = lwc.get(def.BlockData.Name) + if b, ok := d.([]byte); ok && !def.BlockData.Accept(b) { + return rows, nil + } } row[j] = d default: diff --git a/e2pg/integration_test.go b/e2pg/integration_test.go index 02f61161..d85ea298 100644 --- a/e2pg/integration_test.go +++ b/e2pg/integration_test.go @@ -120,24 +120,27 @@ func TestIntegrations(t *testing.T) { where order_hash = '\xdaf50b59a508ee06e269125af28e796477ebf55d22a3c6a24e42d038d9d8d8ee' and tx_hash = '\x713df81a2ab53db1d01531106fc5de43012a401ddc3e0586d522e5c55a162d42' and log_idx = 3 - and offer_token is null - and consideration_recipient = '\x5e97a8773122bde31d44756f271c87893991a6ea' + and abi_idx = 0 + and offer_token = '\x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85' + and consideration_recipient is null `, ` select true from seaport_test where order_hash = '\xdaf50b59a508ee06e269125af28e796477ebf55d22a3c6a24e42d038d9d8d8ee' and tx_hash = '\x713df81a2ab53db1d01531106fc5de43012a401ddc3e0586d522e5c55a162d42' and log_idx = 3 + and abi_idx = 1 and offer_token is null - and consideration_recipient = '\x0000a26b00c1f0df003000390027140000faa719' + and consideration_recipient = '\x5e97a8773122bde31d44756f271c87893991a6ea' `, ` select true from seaport_test where order_hash = '\xdaf50b59a508ee06e269125af28e796477ebf55d22a3c6a24e42d038d9d8d8ee' and tx_hash = '\x713df81a2ab53db1d01531106fc5de43012a401ddc3e0586d522e5c55a162d42' and log_idx = 3 - and offer_token = '\x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85' - and consideration_recipient is null + and abi_idx = 2 + and offer_token is null + and consideration_recipient = '\x0000a26b00c1f0df003000390027140000faa719' `, }, }, diff --git a/e2pg/testdata/seaport.json b/e2pg/testdata/seaport.json index 5d638f8b..e0c11424 100644 --- a/e2pg/testdata/seaport.json +++ b/e2pg/testdata/seaport.json @@ -12,14 +12,16 @@ {"name": "recipient", "type": "bytea"}, {"name": "block_num", "type": "numeric"}, {"name": "tx_hash", "type": "bytea"}, - {"name": "log_idx", "type": "numeric"} + {"name": "log_idx", "type": "numeric"}, + {"name": "abi_idx", "type": "numeric"} ] }, "block": [ {"name": "chain_id", "column": "chain_id"}, {"name": "block_num", "column": "block_num"}, {"name": "tx_hash", "column": "tx_hash", "filter_op": "contains", "filter_arg": ["713df81a2ab53db1d01531106fc5de43012a401ddc3e0586d522e5c55a162d42"]}, - {"name": "log_idx", "column": "log_idx"} + {"name": "log_idx", "column": "log_idx"}, + {"name": "abi_idx", "column": "abi_idx"} ], "event": { "anonymous": false,