diff --git a/go.mod b/go.mod index e7a11b288..c3eb7307e 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( github.com/holiman/uint256 v1.1.1 github.com/huin/goupnp v1.0.1-0.20210310174557-0ca763054c88 github.com/influxdata/influxdb v1.8.3 + github.com/ipfs/go-block-format v0.0.2 github.com/ipfs/go-cid v0.0.7 github.com/ipfs/go-ipfs-blockstore v1.0.1 github.com/ipfs/go-ipfs-ds-help v1.0.0 diff --git a/statediff/db/migrations/00015_create_access_list_table.sql b/statediff/db/migrations/00015_create_access_list_table.sql index a21760489..2e30cd5f3 100644 --- a/statediff/db/migrations/00015_create_access_list_table.sql +++ b/statediff/db/migrations/00015_create_access_list_table.sql @@ -1,15 +1,15 @@ -- +goose Up -CREATE TABLE eth.access_list_entry ( +CREATE TABLE eth.access_list_element ( id SERIAL PRIMARY KEY, - index INTEGER NOT NULL, tx_id INTEGER NOT NULL REFERENCES eth.transaction_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, + index INTEGER NOT NULL, address VARCHAR(66), storage_keys VARCHAR(66)[], UNIQUE (tx_id, index) ); -CREATE INDEX accesss_list_address_index ON eth.access_list_entry USING btree (address); +CREATE INDEX accesss_list_element_address_index ON eth.access_list_element USING btree (address); -- +goose Down -DROP INDEX eth.accesss_list_address_index; -DROP TABLE eth.access_list_entry; +DROP INDEX eth.accesss_list_element_address_index; +DROP TABLE eth.access_list_element; diff --git a/statediff/indexer/indexer.go b/statediff/indexer/indexer.go index 62135e5ba..942bf1952 100644 --- a/statediff/indexer/indexer.go +++ b/statediff/indexer/indexer.go @@ -324,7 +324,10 @@ func (sdi *StateDiffIndexer) processReceiptsAndTxs(tx *sqlx.Tx, args processArgs Data: trx.Data(), CID: txNode.Cid().String(), MhKey: shared.MultihashKeyFromCID(txNode.Cid()), - Type: trx.Type(), + } + txType := trx.Type() + if txType != types.LegacyTxType { + txModel.Type = &txType } txID, err := sdi.dbWriter.upsertTransactionCID(tx, txModel, args.headerID) if err != nil { diff --git a/statediff/indexer/indexer_test.go b/statediff/indexer/indexer_test.go index bb92fa498..92ea557c7 100644 --- a/statediff/indexer/indexer_test.go +++ b/statediff/indexer/indexer_test.go @@ -212,12 +212,68 @@ func TestPublishAndIndexer(t *testing.T) { switch c { case trx1CID.String(): shared.ExpectEqual(t, data, tx1) + var txType *uint8 + pgStr = `SELECT tx_type FROM eth.transaction_cids WHERE cid = $1` + err = db.Get(&txType, pgStr, c) + if err != nil { + t.Fatal(err) + } + if txType != nil { + t.Fatalf("expected nil tx_type, got %d", *txType) + } case trx2CID.String(): shared.ExpectEqual(t, data, tx2) + var txType *uint8 + pgStr = `SELECT tx_type FROM eth.transaction_cids WHERE cid = $1` + err = db.Get(&txType, pgStr, c) + if err != nil { + t.Fatal(err) + } + if txType != nil { + t.Fatalf("expected nil tx_type, got %d", *txType) + } case trx3CID.String(): shared.ExpectEqual(t, data, tx3) + var txType *uint8 + pgStr = `SELECT tx_type FROM eth.transaction_cids WHERE cid = $1` + err = db.Get(&txType, pgStr, c) + if err != nil { + t.Fatal(err) + } + if txType != nil { + t.Fatalf("expected nil tx_type, got %d", *txType) + } case trx4CID.String(): shared.ExpectEqual(t, data, tx4) + var txType *uint8 + pgStr = `SELECT tx_type FROM eth.transaction_cids WHERE cid = $1` + err = db.Get(&txType, pgStr, c) + if err != nil { + t.Fatal(err) + } + if *txType != types.AccessListTxType { + t.Fatalf("expected AccessListTxType (1), got %d", *txType) + } + accessListElementModels := make([]models.AccessListElementModel, 0) + pgStr = `SELECT access_list_element.* FROM eth.access_list_element INNER JOIN eth.transaction_cids ON (tx_id = transaction_cids.id) WHERE cid = $1 ORDER BY access_list_element.index ASC` + err = db.Select(&accessListElementModels, pgStr, c) + if err != nil { + t.Fatal(err) + } + if len(accessListElementModels) != 2 { + t.Fatalf("expected two access list entries, got %d", len(accessListElementModels)) + } + model1 := models.AccessListElementModel{ + Index: accessListElementModels[0].Index, + Address: accessListElementModels[0].Address, + } + model2 := models.AccessListElementModel{ + Index: accessListElementModels[1].Index, + Address: accessListElementModels[1].Address, + StorageKeys: accessListElementModels[1].StorageKeys, + } + shared.ExpectEqual(t, model1, mocks.AccessListEntry1Model) + shared.ExpectEqual(t, model2, mocks.AccessListEntry2Model) } } }) diff --git a/statediff/indexer/mocks/test_data.go b/statediff/indexer/mocks/test_data.go index db9a60156..d0b693fba 100644 --- a/statediff/indexer/mocks/test_data.go +++ b/statediff/indexer/mocks/test_data.go @@ -22,6 +22,8 @@ import ( "crypto/rand" "math/big" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/common" @@ -74,12 +76,32 @@ var ( Data: []byte{}, } + // access list entries + AccessListEntry1 = types.AccessTuple{ + Address: Address, + } + AccessListEntry2 = types.AccessTuple{ + Address: AnotherAddress, + StorageKeys: []common.Hash{common.BytesToHash(StorageLeafKey), common.BytesToHash(MockStorageLeafKey)}, + } + AccessListEntry1Model = models.AccessListElementModel{ + Index: 0, + Address: Address.Hex(), + } + AccessListEntry2Model = models.AccessListElementModel{ + Index: 1, + Address: AnotherAddress.Hex(), + StorageKeys: []string{common.BytesToHash(StorageLeafKey).Hex(), common.BytesToHash(MockStorageLeafKey).Hex()}, + } + // statediff data - storageLocation = common.HexToHash("0") - StorageLeafKey = crypto.Keccak256Hash(storageLocation[:]).Bytes() - StorageValue = common.Hex2Bytes("01") - StoragePartialPath = common.Hex2Bytes("20290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") - StorageLeafNode, _ = rlp.EncodeToBytes([]interface{}{ + storageLocation = common.HexToHash("0") + StorageLeafKey = crypto.Keccak256Hash(storageLocation[:]).Bytes() + mockStorageLocation = common.HexToHash("1") + MockStorageLeafKey = crypto.Keccak256Hash(mockStorageLocation[:]).Bytes() + StorageValue = common.Hex2Bytes("01") + StoragePartialPath = common.Hex2Bytes("20290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") + StorageLeafNode, _ = rlp.EncodeToBytes([]interface{}{ StoragePartialPath, StorageValue, }) @@ -172,9 +194,8 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common Value: big.NewInt(1000), Data: []byte{}, AccessList: types.AccessList{ - types.AccessTuple{ - Address: AnotherAddress, - }, + AccessListEntry1, + AccessListEntry2, }, }) diff --git a/statediff/indexer/models/models.go b/statediff/indexer/models/models.go index 599df8ae9..604cf6b62 100644 --- a/statediff/indexer/models/models.go +++ b/statediff/indexer/models/models.go @@ -60,7 +60,7 @@ type TxModel struct { Dst string `db:"dst"` Src string `db:"src"` Data []byte `db:"tx_data"` - Type uint8 `db:"tx_type"` + Type *uint8 `db:"tx_type"` } // AccessListEntryModel is the db model for eth.access_list_entry diff --git a/statediff/indexer/writer.go b/statediff/indexer/writer.go index b523c057f..e8c0a0398 100644 --- a/statediff/indexer/writer.go +++ b/statediff/indexer/writer.go @@ -69,10 +69,10 @@ func (in *PostgresCIDWriter) upsertUncleCID(tx *sqlx.Tx, uncle models.UncleModel func (in *PostgresCIDWriter) upsertTransactionCID(tx *sqlx.Tx, transaction models.TxModel, headerID int64) (int64, error) { var txID int64 - err := tx.QueryRowx(`INSERT INTO eth.transaction_cids (header_id, tx_hash, cid, dst, src, index, mh_key, tx_data) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) - ON CONFLICT (header_id, tx_hash) DO UPDATE SET (cid, dst, src, index, mh_key, tx_data) = ($3, $4, $5, $6, $7, $8) + err := tx.QueryRowx(`INSERT INTO eth.transaction_cids (header_id, tx_hash, cid, dst, src, index, mh_key, tx_data, tx_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (header_id, tx_hash) DO UPDATE SET (cid, dst, src, index, mh_key, tx_data, tx_type) = ($3, $4, $5, $6, $7, $8, $9) RETURNING id`, - headerID, transaction.TxHash, transaction.CID, transaction.Dst, transaction.Src, transaction.Index, transaction.MhKey, transaction.Data).Scan(&txID) + headerID, transaction.TxHash, transaction.CID, transaction.Dst, transaction.Src, transaction.Index, transaction.MhKey, transaction.Data, transaction.Type).Scan(&txID) if err != nil { return 0, fmt.Errorf("error upserting transaction_cids entry: %v", err) }