diff --git a/core/blockchain_db_observer.go b/core/blockchain_db_observer.go index 23bb2fb7..9c187f1c 100644 --- a/core/blockchain_db_observer.go +++ b/core/blockchain_db_observer.go @@ -10,18 +10,24 @@ type BlockchainDBObserver struct { } func (observer BlockchainDBObserver) NotifyBlockAdded(block Block) { - observer.Db.MustExec("Insert INTO blocks "+ - "(block_number, block_gaslimit, block_gasused, block_time) "+ - "VALUES ($1, $2, $3, $4)", - block.Number.Int64(), block.GasLimit.Int64(), block.GasUsed.Int64(), block.Time.Int64()) + insertedBlockId := saveBlock(observer, block) + saveTransactions(insertedBlockId, block.Transactions, observer) +} - for _, transaction := range block.Transactions { - observer.saveTransaction(transaction) +func saveBlock(observer BlockchainDBObserver, block Block) int64 { + insertedBlock := observer.Db.QueryRow("Insert INTO blocks "+ + "(block_number, block_gaslimit, block_gasused, block_time) "+ + "VALUES ($1, $2, $3, $4) RETURNING id", + block.Number.Int64(), block.GasLimit.Int64(), block.GasUsed.Int64(), block.Time.Int64()) + var blockId int64 + insertedBlock.Scan(&blockId) + return blockId +} + +func saveTransactions(blockId int64, transactions []Transaction, observer BlockchainDBObserver) { + for _, transaction := range transactions { + observer.Db.MustExec("Insert INTO transactions "+ + "(block_id, tx_hash, tx_nonce, tx_to, tx_gaslimit, tx_gasprice, tx_value) VALUES ($1, $2, $3, $4, $5, $6, $7)", + blockId, transaction.Hash, transaction.Nonce, transaction.To, transaction.GasLimit, transaction.GasPrice, transaction.Value) } } - -func (observer BlockchainDBObserver) saveTransaction(transaction Transaction) { - observer.Db.MustExec("Insert INTO transactions "+ - "(tx_hash, tx_nonce, tx_to, tx_gaslimit, tx_gasprice, tx_value) VALUES ($1, $2, $3, $4, $5, $6)", - transaction.Hash, transaction.Nonce, transaction.To, transaction.GasLimit, transaction.GasPrice, transaction.Value) -} diff --git a/core/blockchain_db_observer_test.go b/core/blockchain_db_observer_test.go index dae1a78b..05d36d45 100644 --- a/core/blockchain_db_observer_test.go +++ b/core/blockchain_db_observer_test.go @@ -30,8 +30,8 @@ var _ = Describe("Saving blocks to the database", func() { BeforeEach(func() { db, err = sqlx.Connect("postgres", pgConfig) - db.MustExec("DELETE FROM blocks") db.MustExec("DELETE FROM transactions") + db.MustExec("DELETE FROM blocks") }) It("implements the observer interface", func() { @@ -146,6 +146,49 @@ var _ = Describe("Saving blocks to the database", func() { Expect(savedTransaction.GasPrice).To(Equal(gasPrice)) Expect(savedTransaction.Value).To(Equal(value)) }) + + It("associates the transaction with the block", func() { + gasLimit := int64(5000) + + txRecord := core.Transaction{} + blockNumber := big.NewInt(1) + gasUsed := big.NewInt(10) + blockTime := big.NewInt(1508981640) + block := core.Block{ + Number: blockNumber, + GasLimit: big.NewInt(gasLimit), + GasUsed: gasUsed, + Time: blockTime, + Transactions: []core.Transaction{txRecord}, + } + + observer := core.BlockchainDBObserver{Db: db} + observer.NotifyBlockAdded(block) + + blockRows, err := db.Query("SELECT id FROM blocks") + Expect(err).To(BeNil()) + + var actualBlockIds []int64 + for blockRows.Next() { + var actualBlockId int64 + blockRows.Scan(&actualBlockId) + actualBlockIds = append(actualBlockIds, actualBlockId) + } + + transactionRows, err := db.Query("SELECT block_id FROM transactions") + Expect(err).To(BeNil()) + + var transactionBlockIds []int64 + for transactionRows.Next() { + var transactionBlockId int64 + transactionRows.Scan(&transactionBlockId) + transactionBlockIds = append(transactionBlockIds, transactionBlockId) + } + + Expect(len(actualBlockIds)).To(Equal(1)) + Expect(len(transactionBlockIds)).To(Equal(1)) + Expect(transactionBlockIds[0]).To(Equal(actualBlockIds[0])) + }) }) }) diff --git a/migrations/1509460207_add_block_id_to_transactions.down.sql b/migrations/1509460207_add_block_id_to_transactions.down.sql new file mode 100644 index 00000000..ef380fe4 --- /dev/null +++ b/migrations/1509460207_add_block_id_to_transactions.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE transactions + DROP COLUMN block_id \ No newline at end of file diff --git a/migrations/1509460207_add_block_id_to_transactions.up.sql b/migrations/1509460207_add_block_id_to_transactions.up.sql new file mode 100644 index 00000000..0132dbc7 --- /dev/null +++ b/migrations/1509460207_add_block_id_to_transactions.up.sql @@ -0,0 +1,5 @@ +ALTER TABLE transactions + ADD COLUMN block_id INTEGER NOT NULL, + ADD CONSTRAINT fk_test + FOREIGN KEY (block_id) + REFERENCES blocks (id) diff --git a/migrations/schema.sql b/migrations/schema.sql index 44a5f4f4..2c938aa5 100644 --- a/migrations/schema.sql +++ b/migrations/schema.sql @@ -87,7 +87,8 @@ CREATE TABLE transactions ( tx_to character varying(66), tx_gaslimit numeric, tx_gasprice numeric, - tx_value numeric + tx_value numeric, + block_id integer NOT NULL ); @@ -148,6 +149,15 @@ ALTER TABLE ONLY transactions ADD CONSTRAINT transactions_pkey PRIMARY KEY (id); +-- +-- Name: transactions fk_test; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY transactions + ADD CONSTRAINT fk_test FOREIGN KEY (block_id) REFERENCES blocks(id); + + -- -- PostgreSQL database dump complete -- +