full_sync and light_sync receipt tables and light receipt repository methods and test

This commit is contained in:
Ian Norden
2019-04-05 16:36:48 -05:00
parent 4d0f7ee1bb
commit c1940c3e58
15 changed files with 304 additions and 30 deletions
@@ -19,10 +19,11 @@ package repositories
import (
"database/sql"
"errors"
"github.com/jmoiron/sqlx"
log "github.com/sirupsen/logrus"
"github.com/vulcanize/vulcanizedb/libraries/shared/utilities"
"github.com/vulcanize/vulcanizedb/libraries/shared/utilities"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
@@ -260,7 +261,7 @@ func (blockRepository BlockRepository) createReceipt(tx *sqlx.Tx, blockId int64,
//Not currently persisting log bloom filters
var receiptId int
err := tx.QueryRow(
`INSERT INTO receipts
`INSERT INTO full_sync_receipts
(contract_address, tx_hash, cumulative_gas_used, gas_used, state_root, status, block_id)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id`,
@@ -19,6 +19,7 @@ package repositories
import (
"database/sql"
"errors"
"github.com/jmoiron/sqlx"
log "github.com/sirupsen/logrus"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
@@ -64,6 +65,49 @@ func (repository HeaderRepository) CreateTransactions(headerID int64, transactio
return nil
}
func (repository HeaderRepository) CreateTransactionInTx(tx *sqlx.Tx, headerID int64, transaction core.TransactionModel) (int64, error) {
var txId int64
err := tx.QueryRowx(`INSERT INTO public.light_sync_transactions
(header_id, hash, gaslimit, gasprice, input_data, nonce, raw, tx_from, tx_index, tx_to, "value")
VALUES ($1, $2, $3::NUMERIC, $4::NUMERIC, $5, $6::NUMERIC, $7, $8, $9::NUMERIC, $10, $11::NUMERIC)
ON CONFLICT (header_id, hash) DO UPDATE
SET (gaslimit, gasprice, input_data, nonce, raw, tx_from, tx_index, tx_to, "value") = ($3::NUMERIC, $4::NUMERIC, $5, $6::NUMERIC, $7, $8, $9::NUMERIC, $10, $11::NUMERIC)
RETURNING id`,
headerID, transaction.Hash, transaction.GasLimit, transaction.GasPrice,
transaction.Data, transaction.Nonce, transaction.Raw, transaction.From,
transaction.TxIndex, transaction.To, transaction.Value).Scan(&txId)
if err != nil {
log.Error("header_repository: error inserting transaction: ", err)
return txId, err
}
return txId, err
}
func (repository HeaderRepository) CreateReceipt(headerID, transactionID int64, receipt core.Receipt) error {
_, err := repository.database.Exec(`INSERT INTO public.light_sync_receipts
(header_id, transaction_id, contract_address, cumulative_gas_used, gas_used, state_root, status, tx_hash)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT DO NOTHING`,
headerID, transactionID, receipt.ContractAddress, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.StateRoot, receipt.Status, receipt.TxHash)
return err
}
func (repository HeaderRepository) CreateReceiptInTx(tx *sqlx.Tx, headerID, transactionID int64, receipt core.Receipt) (int64, error) {
var receiptId int64
err := tx.QueryRowx(`INSERT INTO public.light_sync_receipts
(header_id, transaction_id, contract_address, cumulative_gas_used, gas_used, state_root, status, tx_hash)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (header_id, transaction_id) DO UPDATE
SET (contract_address, cumulative_gas_used, gas_used, state_root, status, tx_hash) = ($3, $4::NUMERIC, $5::NUMERIC, $6, $7, $8)
RETURNING id`,
headerID, transactionID, receipt.ContractAddress, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.StateRoot, receipt.Status, receipt.TxHash).Scan(&receiptId)
if err != nil {
log.Error("header_repository: error inserting receipt: ", err)
return receiptId, err
}
return receiptId, err
}
func (repository HeaderRepository) GetHeader(blockNumber int64) (core.Header, error) {
var header core.Header
err := repository.database.Get(&header, `SELECT id, block_number, hash, raw, block_timestamp FROM headers WHERE block_number = $1 AND eth_node_fingerprint = $2`,
@@ -180,6 +180,124 @@ var _ = Describe("Block header repository", func() {
})
})
Describe("creating a receipt", func() {
It("adds a receipt in a tx", func() {
headerID, err := repo.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
fromAddress := common.HexToAddress("0x1234")
toAddress := common.HexToAddress("0x5678")
txHash := common.HexToHash("0x9876")
txIndex := big.NewInt(123)
transaction := core.TransactionModel{
Data: []byte{},
From: fromAddress.Hex(),
GasLimit: 0,
GasPrice: 0,
Hash: txHash.Hex(),
Nonce: 0,
Raw: []byte{},
To: toAddress.Hex(),
TxIndex: txIndex.Int64(),
Value: "0",
}
tx, err := db.Beginx()
Expect(err).ToNot(HaveOccurred())
txId, txErr := repo.CreateTransactionInTx(tx, headerID, transaction)
Expect(txErr).ToNot(HaveOccurred())
contractAddr := common.HexToAddress("0x1234")
stateRoot := common.HexToHash("0x5678")
var gasUsed uint64 = 10
var cumulativeGasUsed uint64 = 100
receipt := core.Receipt{
ContractAddress: contractAddr.Hex(),
TxHash: txHash.Hex(),
GasUsed: gasUsed,
CumulativeGasUsed: cumulativeGasUsed,
StateRoot: stateRoot.Hex(),
}
_, receiptErr := repo.CreateReceiptInTx(tx, headerID, txId, receipt)
commitErr := tx.Commit()
Expect(commitErr).ToNot(HaveOccurred())
Expect(receiptErr).ToNot(HaveOccurred())
type idModel struct {
TransactionId int64 `db:"transaction_id"`
core.ReceiptModel
}
var dbReceipt idModel
err = db.Get(&dbReceipt,
`SELECT transaction_id, contract_address, cumulative_gas_used, gas_used, state_root, status, tx_hash
FROM public.light_sync_receipts WHERE header_id = $1`, headerID)
Expect(err).NotTo(HaveOccurred())
Expect(dbReceipt.TransactionId).To(Equal(txId))
Expect(dbReceipt.TxHash).To(Equal(txHash.Hex()))
Expect(dbReceipt.ContractAddress).To(Equal(contractAddr.Hex()))
Expect(dbReceipt.CumulativeGasUsed).To(Equal("100"))
Expect(dbReceipt.GasUsed).To(Equal("10"))
Expect(dbReceipt.StateRoot).To(Equal(stateRoot.Hex()))
})
It("adds a receipt in standalone query", func() {
headerID, err := repo.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
fromAddress := common.HexToAddress("0x1234")
toAddress := common.HexToAddress("0x5678")
txHash := common.HexToHash("0x9876")
txIndex := big.NewInt(123)
transaction := core.TransactionModel{
Data: []byte{},
From: fromAddress.Hex(),
GasLimit: 0,
GasPrice: 0,
Hash: txHash.Hex(),
Nonce: 0,
Raw: []byte{},
To: toAddress.Hex(),
TxIndex: txIndex.Int64(),
Value: "0",
}
tx, err := db.Beginx()
Expect(err).ToNot(HaveOccurred())
txId, txErr := repo.CreateTransactionInTx(tx, headerID, transaction)
commitErr := tx.Commit()
Expect(commitErr).ToNot(HaveOccurred())
Expect(txErr).ToNot(HaveOccurred())
contractAddr := common.HexToAddress("0x1234")
stateRoot := common.HexToHash("0x5678")
var gasUsed uint64 = 10
var cumulativeGasUsed uint64 = 100
receipt := core.Receipt{
ContractAddress: contractAddr.Hex(),
TxHash: txHash.Hex(),
GasUsed: gasUsed,
CumulativeGasUsed: cumulativeGasUsed,
StateRoot: stateRoot.Hex(),
}
receiptErr := repo.CreateReceipt(headerID, txId, receipt)
Expect(receiptErr).ToNot(HaveOccurred())
type idModel struct {
TransactionId int64 `db:"transaction_id"`
core.ReceiptModel
}
var dbReceipt idModel
err = db.Get(&dbReceipt,
`SELECT transaction_id, contract_address, cumulative_gas_used, gas_used, state_root, status, tx_hash
FROM public.light_sync_receipts WHERE header_id = $1`, headerID)
Expect(err).NotTo(HaveOccurred())
Expect(dbReceipt.TransactionId).To(Equal(txId))
Expect(dbReceipt.TxHash).To(Equal(txHash.Hex()))
Expect(dbReceipt.ContractAddress).To(Equal(contractAddr.Hex()))
Expect(dbReceipt.CumulativeGasUsed).To(Equal("100"))
Expect(dbReceipt.GasUsed).To(Equal("10"))
Expect(dbReceipt.StateRoot).To(Equal(stateRoot.Hex()))
})
})
Describe("creating a transaction", func() {
var (
headerID int64
@@ -245,6 +363,87 @@ var _ = Describe("Block header repository", func() {
})
})
Describe("creating a transaction in a sqlx tx", func() {
It("adds a transaction", func() {
headerID, err := repo.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
fromAddress := common.HexToAddress("0x1234")
toAddress := common.HexToAddress("0x5678")
txHash := common.HexToHash("0x9876")
txIndex := big.NewInt(123)
transaction := core.TransactionModel{
Data: []byte{},
From: fromAddress.Hex(),
GasLimit: 0,
GasPrice: 0,
Hash: txHash.Hex(),
Nonce: 0,
Raw: []byte{},
To: toAddress.Hex(),
TxIndex: txIndex.Int64(),
Value: "0",
}
tx, err := db.Beginx()
Expect(err).ToNot(HaveOccurred())
_, insertErr := repo.CreateTransactionInTx(tx, headerID, transaction)
commitErr := tx.Commit()
Expect(commitErr).ToNot(HaveOccurred())
Expect(insertErr).NotTo(HaveOccurred())
var dbTransaction core.TransactionModel
err = db.Get(&dbTransaction,
`SELECT hash, gaslimit, gasprice, input_data, nonce, raw, tx_from, tx_index, tx_to, "value"
FROM public.light_sync_transactions WHERE header_id = $1`, headerID)
Expect(err).NotTo(HaveOccurred())
Expect(dbTransaction).To(Equal(transaction))
})
It("silently upserts", func() {
headerID, err := repo.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
fromAddress := common.HexToAddress("0x1234")
toAddress := common.HexToAddress("0x5678")
txHash := common.HexToHash("0x9876")
txIndex := big.NewInt(123)
transaction := core.TransactionModel{
Data: []byte{},
From: fromAddress.Hex(),
GasLimit: 0,
GasPrice: 0,
Hash: txHash.Hex(),
Nonce: 0,
Raw: []byte{},
Receipt: core.Receipt{},
To: toAddress.Hex(),
TxIndex: txIndex.Int64(),
Value: "0",
}
tx1, err := db.Beginx()
Expect(err).ToNot(HaveOccurred())
txId1, insertErr := repo.CreateTransactionInTx(tx1, headerID, transaction)
commit1Err := tx1.Commit()
Expect(commit1Err).ToNot(HaveOccurred())
Expect(insertErr).NotTo(HaveOccurred())
tx2, err := db.Beginx()
Expect(err).ToNot(HaveOccurred())
txId2, insertErr := repo.CreateTransactionInTx(tx2, headerID, transaction)
commit2Err := tx2.Commit()
Expect(commit2Err).ToNot(HaveOccurred())
Expect(insertErr).NotTo(HaveOccurred())
Expect(txId1).To(Equal(txId2))
var dbTransactions []core.TransactionModel
err = db.Select(&dbTransactions,
`SELECT hash, gaslimit, gasprice, input_data, nonce, raw, tx_from, tx_index, tx_to, "value"
FROM public.light_sync_transactions WHERE header_id = $1`, headerID)
Expect(err).NotTo(HaveOccurred())
Expect(len(dbTransactions)).To(Equal(1))
})
})
Describe("Getting a header", func() {
It("returns header if it exists", func() {
_, err = repo.CreateOrUpdateHeader(header)
@@ -56,7 +56,7 @@ func (receiptRepository ReceiptRepository) CreateReceiptsAndLogs(blockId int64,
func createReceipt(receipt core.Receipt, blockId int64, tx *sqlx.Tx) (int64, error) {
var receiptId int64
err := tx.QueryRow(
`INSERT INTO receipts
`INSERT INTO full_sync_receipts
(contract_address, tx_hash, cumulative_gas_used, gas_used, state_root, status, block_id)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id`,
@@ -87,7 +87,7 @@ func (receiptRepository ReceiptRepository) CreateReceipt(blockId int64, receipt
tx, _ := receiptRepository.DB.Beginx()
var receiptId int64
err := tx.QueryRow(
`INSERT INTO receipts
`INSERT INTO full_sync_receipts
(contract_address, tx_hash, cumulative_gas_used, gas_used, state_root, status, block_id)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id`,
@@ -109,7 +109,7 @@ func (receiptRepository ReceiptRepository) GetReceipt(txHash string) (core.Recei
gas_used,
state_root,
status
FROM receipts
FROM full_sync_receipts
WHERE tx_hash = $1`, txHash)
receipt, err := loadReceipt(row)
if err != nil {