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,
timestamp NUMERIC NOT NULL,
times_validated INTEGER NOT NULL DEFAULT 1,
base_fee BIGINT NOT NULL,
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(),
UncleRoot: header.UncleHash.String(),
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/common"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/statediff/indexer"
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs/ipld"
"github.com/ethereum/go-ethereum/statediff/indexer/mocks"
@ -45,11 +44,11 @@ var (
ind *indexer.StateDiffIndexer
ipfsPgGet = `SELECT data FROM public.blocks
WHERE key = $1`
tx1, tx2, tx3, tx4, rct1, rct2, rct3, rct4 []byte
mockBlock *types.Block
headerCID, trx1CID, trx2CID, trx3CID, trx4CID cid.Cid
rct1CID, rct2CID, rct3CID, rct4CID cid.Cid
state1CID, state2CID, storageCID cid.Cid
tx1, tx2, tx3, tx4, tx5, rct1, rct2, rct3, rct4, rct5 []byte
mockBlock *types.Block
headerCID, trx1CID, trx2CID, trx3CID, trx4CID, trx5CID cid.Cid
rct1CID, rct2CID, rct3CID, rct4CID, rct5CID cid.Cid
state1CID, state2CID, storageCID cid.Cid
)
func expectTrue(t *testing.T, value bool) {
@ -88,6 +87,11 @@ func init() {
copy(tx4, buf.Bytes())
buf.Reset()
txs.EncodeIndex(4, buf)
tx5 = make([]byte, buf.Len())
copy(tx5, buf.Bytes())
buf.Reset()
rcts.EncodeIndex(0, buf)
rct1 = make([]byte, buf.Len())
copy(rct1, buf.Bytes())
@ -108,15 +112,22 @@ func init() {
copy(rct4, buf.Bytes())
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)
trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx1, multihash.KECCAK_256)
trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx2, multihash.KECCAK_256)
trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx3, 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)
rct2CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct2, multihash.KECCAK_256)
rct3CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, rct3, 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)
state2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, mocks.AccountLeafNode, 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 {
t.Fatal(err)
}
ind = indexer.NewStateDiffIndexer(params.MainnetChainConfig, db)
ind = indexer.NewStateDiffIndexer(mocks.TestConfig, db)
var tx *indexer.BlockTx
tx, err = ind.PushBlock(
mockBlock,
@ -198,11 +209,12 @@ func TestPublishAndIndexer(t *testing.T) {
if err != nil {
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, trx2CID.String()))
expectTrue(t, shared.ListContainsString(trxs, trx3CID.String()))
expectTrue(t, shared.ListContainsString(trxs, trx4CID.String()))
expectTrue(t, shared.ListContainsString(trxs, trx5CID.String()))
// and published
for _, c := range trxs {
dc, err := cid.Decode(c)
@ -281,6 +293,17 @@ func TestPublishAndIndexer(t *testing.T) {
}
shared.ExpectEqual(t, model1, mocks.AccessListEntry1Model)
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 {
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, rct2CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct3CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct4CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct5CID.String()))
// and published
for _, c := range rcts {
dc, err := cid.Decode(c)
@ -353,6 +377,15 @@ func TestPublishAndIndexer(t *testing.T) {
t.Fatal(err)
}
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
var (
// block data
BlockNumber = big.NewInt(12244001)
// TODO: Update this to `MainnetChainConfig` when `LondonBlock` is added
TestConfig = params.RinkebyChainConfig
BlockNumber = TestConfig.LondonBlock
MockHeader = types.Header{
Time: 0,
Number: new(big.Int).Set(BlockNumber),
@ -49,6 +51,7 @@ var (
ReceiptHash: common.HexToHash("0x0"),
Difficulty: big.NewInt(5000000),
Extra: []byte{},
BaseFee: big.NewInt(params.InitialBaseFee),
}
MockTransactions, MockReceipts, SenderAddr = createTransactionsAndReceipts()
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{})
trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode)
trx4 := types.NewTx(&types.AccessListTx{
ChainID: big.NewInt(1),
ChainID: TestConfig.ChainID,
Nonce: 0,
GasPrice: big.NewInt(100),
Gas: 50,
@ -198,8 +201,22 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common
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()
mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader)
if err != nil {
@ -219,13 +236,18 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common
}
signedTrx4, err := types.SignTx(trx4, transactionSigner, mockPrvKey)
if err != nil {
println(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
if err != nil {
log.Crit(err.Error())
}
// make receipts
mockReceipt1 := types.NewReceipt(nil, false, 50)
mockReceipt1.Logs = []*types.Log{MockLog1}
@ -244,6 +266,14 @@ func createTransactionsAndReceipts() (types.Transactions, types.Receipts, common
Logs: []*types.Log{},
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"`
Timestamp uint64 `db:"timestamp"`
TimesValidated int64 `db:"times_validated"`
BaseFee string `db:"base_fee"`
}
// UncleModel is the db model for eth.uncle_cids
@ -63,7 +64,7 @@ type TxModel struct {
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 {
ID int64 `db:"id"`
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) {
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)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
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)
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, $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, base_fee) = ($3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, eth.header_cids.times_validated + 1, $16)
RETURNING id`,
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 {
return 0, fmt.Errorf("error upserting header_cids entry: %v", err)
}