Add support for Dynamic txn(EIP-1559).

This commit is contained in:
Arijit Das 2021-06-29 13:21:37 +05:30
parent 4f627f614f
commit a1a02a097d
6 changed files with 85 additions and 19 deletions

View File

@ -16,6 +16,7 @@ CREATE TABLE eth.header_cids (
bloom BYTEA NOT NULL, bloom BYTEA NOT NULL,
timestamp NUMERIC NOT NULL, timestamp NUMERIC NOT NULL,
times_validated INTEGER NOT NULL DEFAULT 1, times_validated INTEGER NOT NULL DEFAULT 1,
base_fee BIGINT NOT NULL,
UNIQUE (block_number, block_hash) UNIQUE (block_number, block_hash)
); );

View File

@ -229,6 +229,7 @@ func (sdi *StateDiffIndexer) processHeader(tx *sqlx.Tx, header *types.Header, he
TxRoot: header.TxHash.String(), TxRoot: header.TxHash.String(),
UncleRoot: header.UncleHash.String(), UncleRoot: header.UncleHash.String(),
Timestamp: header.Time, Timestamp: header.Time,
BaseFee: header.BaseFee.String(),
}) })
} }

View File

@ -25,7 +25,6 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/statediff/indexer" "github.com/ethereum/go-ethereum/statediff/indexer"
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs/ipld" "github.com/ethereum/go-ethereum/statediff/indexer/ipfs/ipld"
"github.com/ethereum/go-ethereum/statediff/indexer/mocks" "github.com/ethereum/go-ethereum/statediff/indexer/mocks"
@ -45,10 +44,10 @@ var (
ind *indexer.StateDiffIndexer ind *indexer.StateDiffIndexer
ipfsPgGet = `SELECT data FROM public.blocks ipfsPgGet = `SELECT data FROM public.blocks
WHERE key = $1` WHERE key = $1`
tx1, tx2, tx3, tx4, rct1, rct2, rct3, rct4 []byte tx1, tx2, tx3, tx4, tx5, rct1, rct2, rct3, rct4, rct5 []byte
mockBlock *types.Block mockBlock *types.Block
headerCID, trx1CID, trx2CID, trx3CID, trx4CID cid.Cid headerCID, trx1CID, trx2CID, trx3CID, trx4CID, trx5CID cid.Cid
rct1CID, rct2CID, rct3CID, rct4CID cid.Cid rct1CID, rct2CID, rct3CID, rct4CID, rct5CID cid.Cid
state1CID, state2CID, storageCID cid.Cid state1CID, state2CID, storageCID cid.Cid
) )
@ -88,6 +87,11 @@ func init() {
copy(tx4, buf.Bytes()) copy(tx4, buf.Bytes())
buf.Reset() buf.Reset()
txs.EncodeIndex(4, buf)
tx5 = make([]byte, buf.Len())
copy(tx5, buf.Bytes())
buf.Reset()
rcts.EncodeIndex(0, buf) rcts.EncodeIndex(0, buf)
rct1 = make([]byte, buf.Len()) rct1 = make([]byte, buf.Len())
copy(rct1, buf.Bytes()) copy(rct1, buf.Bytes())
@ -108,15 +112,22 @@ func init() {
copy(rct4, buf.Bytes()) copy(rct4, buf.Bytes())
buf.Reset() buf.Reset()
rcts.EncodeIndex(4, buf)
rct5 = make([]byte, buf.Len())
copy(rct5, buf.Bytes())
buf.Reset()
headerCID, _ = ipld.RawdataToCid(ipld.MEthHeader, mocks.MockHeaderRlp, multihash.KECCAK_256) headerCID, _ = ipld.RawdataToCid(ipld.MEthHeader, mocks.MockHeaderRlp, multihash.KECCAK_256)
trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx1, multihash.KECCAK_256) trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx1, multihash.KECCAK_256)
trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx2, multihash.KECCAK_256) trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx2, multihash.KECCAK_256)
trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx3, multihash.KECCAK_256) trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx3, multihash.KECCAK_256)
trx4CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx4, multihash.KECCAK_256) trx4CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx4, multihash.KECCAK_256)
trx5CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx5, multihash.KECCAK_256)
rct1CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct1, multihash.KECCAK_256) rct1CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct1, multihash.KECCAK_256)
rct2CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct2, multihash.KECCAK_256) rct2CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct2, multihash.KECCAK_256)
rct3CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct3, multihash.KECCAK_256) rct3CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct3, multihash.KECCAK_256)
rct4CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct4, multihash.KECCAK_256) rct4CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct4, multihash.KECCAK_256)
rct5CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct5, multihash.KECCAK_256)
state1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, mocks.ContractLeafNode, multihash.KECCAK_256) state1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, mocks.ContractLeafNode, multihash.KECCAK_256)
state2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, mocks.AccountLeafNode, multihash.KECCAK_256) state2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, mocks.AccountLeafNode, multihash.KECCAK_256)
storageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, mocks.StorageLeafNode, multihash.KECCAK_256) storageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, mocks.StorageLeafNode, multihash.KECCAK_256)
@ -127,7 +138,7 @@ func setup(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
ind = indexer.NewStateDiffIndexer(params.MainnetChainConfig, db) ind = indexer.NewStateDiffIndexer(mocks.TestConfig, db)
var tx *indexer.BlockTx var tx *indexer.BlockTx
tx, err = ind.PushBlock( tx, err = ind.PushBlock(
mockBlock, mockBlock,
@ -198,11 +209,12 @@ func TestPublishAndIndexer(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
shared.ExpectEqual(t, len(trxs), 4) shared.ExpectEqual(t, len(trxs), 5)
expectTrue(t, shared.ListContainsString(trxs, trx1CID.String())) expectTrue(t, shared.ListContainsString(trxs, trx1CID.String()))
expectTrue(t, shared.ListContainsString(trxs, trx2CID.String())) expectTrue(t, shared.ListContainsString(trxs, trx2CID.String()))
expectTrue(t, shared.ListContainsString(trxs, trx3CID.String())) expectTrue(t, shared.ListContainsString(trxs, trx3CID.String()))
expectTrue(t, shared.ListContainsString(trxs, trx4CID.String())) expectTrue(t, shared.ListContainsString(trxs, trx4CID.String()))
expectTrue(t, shared.ListContainsString(trxs, trx5CID.String()))
// and published // and published
for _, c := range trxs { for _, c := range trxs {
dc, err := cid.Decode(c) dc, err := cid.Decode(c)
@ -281,6 +293,17 @@ func TestPublishAndIndexer(t *testing.T) {
} }
shared.ExpectEqual(t, model1, mocks.AccessListEntry1Model) shared.ExpectEqual(t, model1, mocks.AccessListEntry1Model)
shared.ExpectEqual(t, model2, mocks.AccessListEntry2Model) shared.ExpectEqual(t, model2, mocks.AccessListEntry2Model)
case trx5CID.String():
shared.ExpectEqual(t, data, tx5)
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.DynamicFeeTxType {
t.Fatalf("expected DynamicFeeTxType (2), got %d", *txType)
}
} }
} }
}) })
@ -298,11 +321,12 @@ func TestPublishAndIndexer(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
shared.ExpectEqual(t, len(rcts), 4) shared.ExpectEqual(t, len(rcts), 5)
expectTrue(t, shared.ListContainsString(rcts, rct1CID.String())) expectTrue(t, shared.ListContainsString(rcts, rct1CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct2CID.String())) expectTrue(t, shared.ListContainsString(rcts, rct2CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct3CID.String())) expectTrue(t, shared.ListContainsString(rcts, rct3CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct4CID.String())) expectTrue(t, shared.ListContainsString(rcts, rct4CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct5CID.String()))
// and published // and published
for _, c := range rcts { for _, c := range rcts {
dc, err := cid.Decode(c) dc, err := cid.Decode(c)
@ -353,6 +377,15 @@ func TestPublishAndIndexer(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
shared.ExpectEqual(t, postState, mocks.ExpectedPostState3) shared.ExpectEqual(t, postState, mocks.ExpectedPostState3)
case rct5CID.String():
shared.ExpectEqual(t, data, rct5)
var postState string
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE cid = $1`
err = db.Get(&postState, pgStr, c)
if err != nil {
t.Fatal(err)
}
shared.ExpectEqual(t, postState, mocks.ExpectedPostState3)
} }
} }
}) })

View File

@ -40,7 +40,9 @@ import (
// Test variables // Test variables
var ( var (
// block data // block data
BlockNumber = big.NewInt(12244001) // TODO: Update this to `MainnetChainConfig` when `LondonBlock` is added
TestConfig = params.RinkebyChainConfig
BlockNumber = TestConfig.LondonBlock
MockHeader = types.Header{ MockHeader = types.Header{
Time: 0, Time: 0,
Number: new(big.Int).Set(BlockNumber), Number: new(big.Int).Set(BlockNumber),
@ -49,6 +51,7 @@ var (
ReceiptHash: common.HexToHash("0x0"), ReceiptHash: common.HexToHash("0x0"),
Difficulty: big.NewInt(5000000), Difficulty: big.NewInt(5000000),
Extra: []byte{}, Extra: []byte{},
BaseFee: big.NewInt(params.InitialBaseFee),
} }
MockTransactions, MockReceipts, SenderAddr = createTransactionsAndReceipts() MockTransactions, MockReceipts, SenderAddr = createTransactionsAndReceipts()
MockBlock = types.NewBlock(&MockHeader, MockTransactions, nil, MockReceipts, new(trie.Trie)) MockBlock = types.NewBlock(&MockHeader, MockTransactions, nil, MockReceipts, new(trie.Trie))
@ -186,7 +189,7 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common
trx2 := types.NewTransaction(1, AnotherAddress, big.NewInt(2000), 100, big.NewInt(200), []byte{}) trx2 := types.NewTransaction(1, AnotherAddress, big.NewInt(2000), 100, big.NewInt(200), []byte{})
trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode) trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode)
trx4 := types.NewTx(&types.AccessListTx{ trx4 := types.NewTx(&types.AccessListTx{
ChainID: big.NewInt(1), ChainID: TestConfig.ChainID,
Nonce: 0, Nonce: 0,
GasPrice: big.NewInt(100), GasPrice: big.NewInt(100),
Gas: 50, Gas: 50,
@ -198,8 +201,22 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common
AccessListEntry2, AccessListEntry2,
}, },
}) })
trx5 := types.NewTx(&types.DynamicFeeTx{
ChainID: TestConfig.ChainID,
Nonce: 0,
GasTipCap: big.NewInt(100),
GasFeeCap: big.NewInt(100),
Gas: 50,
To: &AnotherAddress,
Value: big.NewInt(1000),
Data: []byte{},
AccessList: types.AccessList{
AccessListEntry1,
AccessListEntry2,
},
})
transactionSigner := types.NewEIP2930Signer(params.MainnetChainConfig.ChainID) transactionSigner := types.MakeSigner(TestConfig, BlockNumber)
mockCurve := elliptic.P256() mockCurve := elliptic.P256()
mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader) mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader)
if err != nil { if err != nil {
@ -219,13 +236,18 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common
} }
signedTrx4, err := types.SignTx(trx4, transactionSigner, mockPrvKey) signedTrx4, err := types.SignTx(trx4, transactionSigner, mockPrvKey)
if err != nil { if err != nil {
println(err.Error())
log.Crit(err.Error()) log.Crit(err.Error())
} }
signedTrx5, err := types.SignTx(trx5, transactionSigner, mockPrvKey)
if err != nil {
log.Crit(err.Error())
}
senderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx senderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx
if err != nil { if err != nil {
log.Crit(err.Error()) log.Crit(err.Error())
} }
// make receipts // make receipts
mockReceipt1 := types.NewReceipt(nil, false, 50) mockReceipt1 := types.NewReceipt(nil, false, 50)
mockReceipt1.Logs = []*types.Log{MockLog1} mockReceipt1.Logs = []*types.Log{MockLog1}
@ -244,6 +266,14 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common
Logs: []*types.Log{}, Logs: []*types.Log{},
TxHash: signedTrx4.Hash(), TxHash: signedTrx4.Hash(),
} }
mockReceipt5 := &types.Receipt{
Type: types.DynamicFeeTxType,
PostState: common.HexToHash("0x3").Bytes(),
Status: types.ReceiptStatusSuccessful,
CumulativeGasUsed: 175,
Logs: []*types.Log{},
TxHash: signedTrx5.Hash(),
}
return types.Transactions{signedTrx1, signedTrx2, signedTrx3, signedTrx4}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3, mockReceipt4}, senderAddr return types.Transactions{signedTrx1, signedTrx2, signedTrx3, signedTrx4, signedTrx5}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3, mockReceipt4, mockReceipt5}, senderAddr
} }

View File

@ -36,6 +36,7 @@ type HeaderModel struct {
Bloom []byte `db:"bloom"` Bloom []byte `db:"bloom"`
Timestamp uint64 `db:"timestamp"` Timestamp uint64 `db:"timestamp"`
TimesValidated int64 `db:"times_validated"` TimesValidated int64 `db:"times_validated"`
BaseFee string `db:"base_fee"`
} }
// UncleModel is the db model for eth.uncle_cids // UncleModel is the db model for eth.uncle_cids
@ -63,7 +64,7 @@ type TxModel struct {
Type *uint8 `db:"tx_type"` Type *uint8 `db:"tx_type"`
} }
// AccessListEntryModel is the db model for eth.access_list_entry // AccessListElementModel is the db model for eth.access_list_entry
type AccessListElementModel struct { type AccessListElementModel struct {
ID int64 `db:"id"` ID int64 `db:"id"`
Index int64 `db:"index"` Index int64 `db:"index"`

View File

@ -44,12 +44,12 @@ func NewPostgresCIDWriter(db *postgres.DB) *PostgresCIDWriter {
func (in *PostgresCIDWriter) upsertHeaderCID(tx *sqlx.Tx, header models.HeaderModel) (int64, error) { func (in *PostgresCIDWriter) upsertHeaderCID(tx *sqlx.Tx, header models.HeaderModel) (int64, error) {
var headerID int64 var headerID int64
err := tx.QueryRowx(`INSERT INTO eth.header_cids (block_number, block_hash, parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated) err := tx.QueryRowx(`INSERT INTO eth.header_cids (block_number, block_hash, parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, base_fee)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
ON CONFLICT (block_number, block_hash) DO UPDATE SET (parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated) = ($3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, eth.header_cids.times_validated + 1) ON CONFLICT (block_number, block_hash) DO UPDATE SET (parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, base_fee) = ($3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, eth.header_cids.times_validated + 1, $16)
RETURNING id`, RETURNING id`,
header.BlockNumber, header.BlockHash, header.ParentHash, header.CID, header.TotalDifficulty, in.db.NodeID, header.Reward, header.StateRoot, header.TxRoot, header.BlockNumber, header.BlockHash, header.ParentHash, header.CID, header.TotalDifficulty, in.db.NodeID, header.Reward, header.StateRoot, header.TxRoot,
header.RctRoot, header.UncleRoot, header.Bloom, header.Timestamp, header.MhKey, 1).Scan(&headerID) header.RctRoot, header.UncleRoot, header.Bloom, header.Timestamp, header.MhKey, 1, header.BaseFee).Scan(&headerID)
if err != nil { if err != nil {
return 0, fmt.Errorf("error upserting header_cids entry: %v", err) return 0, fmt.Errorf("error upserting header_cids entry: %v", err)
} }