From c99218684652bad76f2df6f266efacabd71775c8 Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Wed, 27 Dec 2017 10:50:56 -0600 Subject: [PATCH 1/4] Add Block Miner --- db/migrations/1514392444_add_miner.down.sql | 2 ++ db/migrations/1514392444_add_miner.up.sql | 2 ++ db/schema.sql | 3 ++- pkg/core/block.go | 1 + pkg/geth/geth_block_to_core_block.go | 1 + pkg/geth/geth_block_to_core_block_test.go | 5 ++++- pkg/repositories/postgres.go | 13 ++++++++----- pkg/repositories/testing/helpers.go | 3 +++ 8 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 db/migrations/1514392444_add_miner.down.sql create mode 100644 db/migrations/1514392444_add_miner.up.sql diff --git a/db/migrations/1514392444_add_miner.down.sql b/db/migrations/1514392444_add_miner.down.sql new file mode 100644 index 00000000..417ad684 --- /dev/null +++ b/db/migrations/1514392444_add_miner.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE blocks + DROP COLUMN block_miner; \ No newline at end of file diff --git a/db/migrations/1514392444_add_miner.up.sql b/db/migrations/1514392444_add_miner.up.sql new file mode 100644 index 00000000..2667365b --- /dev/null +++ b/db/migrations/1514392444_add_miner.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE blocks + ADD COLUMN block_miner VARCHAR(42); \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql index 76ac4374..f6a08bf5 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -51,7 +51,8 @@ CREATE TABLE blocks ( block_size bigint, uncle_hash character varying(66), node_id integer NOT NULL, - is_final boolean + is_final boolean, + block_miner character varying(42) ); diff --git a/pkg/core/block.go b/pkg/core/block.go index 6e9f5e53..1d58fe8e 100644 --- a/pkg/core/block.go +++ b/pkg/core/block.go @@ -7,6 +7,7 @@ type Block struct { Hash string Nonce string Number int64 + Miner string ParentHash string Size int64 Time int64 diff --git a/pkg/geth/geth_block_to_core_block.go b/pkg/geth/geth_block_to_core_block.go index 4aa67bfc..05f1d111 100644 --- a/pkg/geth/geth_block_to_core_block.go +++ b/pkg/geth/geth_block_to_core_block.go @@ -28,6 +28,7 @@ func GethBlockToCoreBlock(gethBlock *types.Block, client GethClient) core.Block Hash: gethBlock.Hash().Hex(), Nonce: hexutil.Encode(gethBlock.Header().Nonce[:]), Number: gethBlock.Number().Int64(), + Miner: gethBlock.Coinbase().Hex(), ParentHash: gethBlock.ParentHash().Hex(), Size: gethBlock.Size().Int64(), Time: gethBlock.Time().Int64(), diff --git a/pkg/geth/geth_block_to_core_block_test.go b/pkg/geth/geth_block_to_core_block_test.go index 25ec216d..11e30336 100644 --- a/pkg/geth/geth_block_to_core_block_test.go +++ b/pkg/geth/geth_block_to_core_block_test.go @@ -21,10 +21,11 @@ func (client *FakeGethClient) TransactionSender(ctx context.Context, tx *types.T var _ = Describe("Conversion of GethBlock to core.Block", func() { - It("converts basic Block metada", func() { + It("converts basic Block metadata", func() { difficulty := big.NewInt(1) gasLimit := int64(100000) gasUsed := int64(100000) + miner := common.HexToAddress("0x0000000000000000000000000000000000000123") nonce := types.BlockNonce{10} number := int64(1) time := int64(140000000) @@ -33,6 +34,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { Difficulty: difficulty, GasLimit: big.NewInt(gasLimit), GasUsed: big.NewInt(gasUsed), + Coinbase: miner, Nonce: nonce, Number: big.NewInt(number), ParentHash: common.Hash{64}, @@ -45,6 +47,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { Expect(gethBlock.Difficulty).To(Equal(difficulty.Int64())) Expect(gethBlock.GasLimit).To(Equal(gasLimit)) + Expect(gethBlock.Miner).To(Equal(miner.Hex())) Expect(gethBlock.GasUsed).To(Equal(gasUsed)) Expect(gethBlock.Hash).To(Equal(block.Hash().Hex())) Expect(gethBlock.Nonce).To(Equal(hexutil.Encode(header.Nonce[:]))) diff --git a/pkg/repositories/postgres.go b/pkg/repositories/postgres.go index ebd2f9cb..663da189 100644 --- a/pkg/repositories/postgres.go +++ b/pkg/repositories/postgres.go @@ -198,7 +198,8 @@ func (repository Postgres) FindBlockByNumber(blockNumber int64) (core.Block, err block_parenthash, block_size, uncle_hash, - is_final + is_final, + block_miner FROM blocks WHERE node_id = $1 AND block_number = $2`, repository.nodeId, blockNumber) savedBlock, err := repository.loadBlock(blockRows) @@ -256,10 +257,10 @@ func (repository Postgres) insertBlock(block core.Block) error { tx, _ := repository.Db.BeginTx(context.Background(), nil) err := tx.QueryRow( `INSERT INTO blocks - (node_id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash, is_final) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + (node_id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash, is_final, block_miner) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING id `, - repository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal). + repository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal, block.Miner). Scan(&blockId) if err != nil { tx.Rollback() @@ -305,6 +306,7 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { var blockHash string var blockNonce string var blockNumber int64 + var blockMiner string var blockParentHash string var blockSize int64 var blockTime float64 @@ -313,7 +315,7 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { var gasUsed float64 var uncleHash string var isFinal bool - err := blockRows.Scan(&blockId, &blockNumber, &gasLimit, &gasUsed, &blockTime, &difficulty, &blockHash, &blockNonce, &blockParentHash, &blockSize, &uncleHash, &isFinal) + err := blockRows.Scan(&blockId, &blockNumber, &gasLimit, &gasUsed, &blockTime, &difficulty, &blockHash, &blockNonce, &blockParentHash, &blockSize, &uncleHash, &isFinal, &blockMiner) if err != nil { return core.Block{}, err } @@ -336,6 +338,7 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { Hash: blockHash, Nonce: blockNonce, Number: blockNumber, + Miner: blockMiner, ParentHash: blockParentHash, Size: blockSize, Time: int64(blockTime), diff --git a/pkg/repositories/testing/helpers.go b/pkg/repositories/testing/helpers.go index 70a71d18..e6bc6aa1 100644 --- a/pkg/repositories/testing/helpers.go +++ b/pkg/repositories/testing/helpers.go @@ -61,6 +61,7 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. blockHash := "x123" blockParentHash := "x456" blockNonce := "0x881db2ca900682e9a9" + miner := "x123" blockTime := int64(1508981640) uncleHash := "x789" blockSize := int64(1000) @@ -71,6 +72,7 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. GasUsed: gasUsed, Hash: blockHash, Nonce: blockNonce, + Miner: miner, Number: blockNumber, ParentHash: blockParentHash, Size: blockSize, @@ -87,6 +89,7 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. Expect(savedBlock.GasUsed).To(Equal(gasUsed)) Expect(savedBlock.Hash).To(Equal(blockHash)) Expect(savedBlock.Nonce).To(Equal(blockNonce)) + Expect(savedBlock.Miner).To(Equal(miner)) Expect(savedBlock.Number).To(Equal(blockNumber)) Expect(savedBlock.ParentHash).To(Equal(blockParentHash)) Expect(savedBlock.Size).To(Equal(blockSize)) From cb4e745464dbe5cc58e54e6e9ad50f19bbc9cb84 Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Wed, 27 Dec 2017 12:10:08 -0600 Subject: [PATCH 2/4] Add extra data field --- .../1514397430_add_extra_data.down.sql | 2 ++ db/migrations/1514397430_add_extra_data.up.sql | 2 ++ db/schema.sql | 3 ++- pkg/core/block.go | 5 +++-- pkg/geth/geth_block_to_core_block.go | 1 + pkg/geth/geth_block_to_core_block_test.go | 3 +++ pkg/repositories/postgres.go | 17 ++++++++++------- pkg/repositories/testing/helpers.go | 3 +++ 8 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 db/migrations/1514397430_add_extra_data.down.sql create mode 100644 db/migrations/1514397430_add_extra_data.up.sql diff --git a/db/migrations/1514397430_add_extra_data.down.sql b/db/migrations/1514397430_add_extra_data.down.sql new file mode 100644 index 00000000..0da3cdeb --- /dev/null +++ b/db/migrations/1514397430_add_extra_data.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE blocks + DROP COLUMN block_extra_data; \ No newline at end of file diff --git a/db/migrations/1514397430_add_extra_data.up.sql b/db/migrations/1514397430_add_extra_data.up.sql new file mode 100644 index 00000000..71839271 --- /dev/null +++ b/db/migrations/1514397430_add_extra_data.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE blocks + ADD COLUMN block_extra_data VARCHAR; \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql index f6a08bf5..e4bbce3f 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -52,7 +52,8 @@ CREATE TABLE blocks ( uncle_hash character varying(66), node_id integer NOT NULL, is_final boolean, - block_miner character varying(42) + block_miner character varying(42), + block_extra_data character varying ); diff --git a/pkg/core/block.go b/pkg/core/block.go index 1d58fe8e..a8300a50 100644 --- a/pkg/core/block.go +++ b/pkg/core/block.go @@ -2,16 +2,17 @@ package core type Block struct { Difficulty int64 + ExtraData string GasLimit int64 GasUsed int64 Hash string + IsFinal bool + Miner string Nonce string Number int64 - Miner string ParentHash string Size int64 Time int64 Transactions []Transaction UncleHash string - IsFinal bool } diff --git a/pkg/geth/geth_block_to_core_block.go b/pkg/geth/geth_block_to_core_block.go index 05f1d111..e9895cbd 100644 --- a/pkg/geth/geth_block_to_core_block.go +++ b/pkg/geth/geth_block_to_core_block.go @@ -26,6 +26,7 @@ func GethBlockToCoreBlock(gethBlock *types.Block, client GethClient) core.Block GasLimit: gethBlock.GasLimit().Int64(), GasUsed: gethBlock.GasUsed().Int64(), Hash: gethBlock.Hash().Hex(), + ExtraData: hexutil.Encode(gethBlock.Extra()), Nonce: hexutil.Encode(gethBlock.Header().Nonce[:]), Number: gethBlock.Number().Int64(), Miner: gethBlock.Coinbase().Hex(), diff --git a/pkg/geth/geth_block_to_core_block_test.go b/pkg/geth/geth_block_to_core_block_test.go index 11e30336..065e6d55 100644 --- a/pkg/geth/geth_block_to_core_block_test.go +++ b/pkg/geth/geth_block_to_core_block_test.go @@ -26,6 +26,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { gasLimit := int64(100000) gasUsed := int64(100000) miner := common.HexToAddress("0x0000000000000000000000000000000000000123") + extraData, _ := hexutil.Decode("0xe4b883e5bda9e7a59ee4bb99e9b1bc") nonce := types.BlockNonce{10} number := int64(1) time := int64(140000000) @@ -34,6 +35,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { Difficulty: difficulty, GasLimit: big.NewInt(gasLimit), GasUsed: big.NewInt(gasUsed), + Extra: extraData, Coinbase: miner, Nonce: nonce, Number: big.NewInt(number), @@ -53,6 +55,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { Expect(gethBlock.Nonce).To(Equal(hexutil.Encode(header.Nonce[:]))) Expect(gethBlock.Number).To(Equal(number)) Expect(gethBlock.ParentHash).To(Equal(block.ParentHash().Hex())) + Expect(gethBlock.ExtraData).To(Equal(hexutil.Encode(block.Extra()))) Expect(gethBlock.Size).To(Equal(block.Size().Int64())) Expect(gethBlock.Time).To(Equal(time)) Expect(gethBlock.UncleHash).To(Equal(block.UncleHash().Hex())) diff --git a/pkg/repositories/postgres.go b/pkg/repositories/postgres.go index 663da189..ed7446ae 100644 --- a/pkg/repositories/postgres.go +++ b/pkg/repositories/postgres.go @@ -199,7 +199,8 @@ func (repository Postgres) FindBlockByNumber(blockNumber int64) (core.Block, err block_size, uncle_hash, is_final, - block_miner + block_miner, + block_extra_data FROM blocks WHERE node_id = $1 AND block_number = $2`, repository.nodeId, blockNumber) savedBlock, err := repository.loadBlock(blockRows) @@ -257,10 +258,10 @@ func (repository Postgres) insertBlock(block core.Block) error { tx, _ := repository.Db.BeginTx(context.Background(), nil) err := tx.QueryRow( `INSERT INTO blocks - (node_id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash, is_final, block_miner) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) + (node_id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash, is_final, block_miner, block_extra_data) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) RETURNING id `, - repository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal, block.Miner). + repository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal, block.Miner, block.ExtraData). Scan(&blockId) if err != nil { tx.Rollback() @@ -307,6 +308,7 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { var blockNonce string var blockNumber int64 var blockMiner string + var blockExtraData string var blockParentHash string var blockSize int64 var blockTime float64 @@ -315,7 +317,7 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { var gasUsed float64 var uncleHash string var isFinal bool - err := blockRows.Scan(&blockId, &blockNumber, &gasLimit, &gasUsed, &blockTime, &difficulty, &blockHash, &blockNonce, &blockParentHash, &blockSize, &uncleHash, &isFinal, &blockMiner) + err := blockRows.Scan(&blockId, &blockNumber, &gasLimit, &gasUsed, &blockTime, &difficulty, &blockHash, &blockNonce, &blockParentHash, &blockSize, &uncleHash, &isFinal, &blockMiner, &blockExtraData) if err != nil { return core.Block{}, err } @@ -333,18 +335,19 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { transactions := repository.loadTransactions(transactionRows) return core.Block{ Difficulty: difficulty, + ExtraData: blockExtraData, GasLimit: int64(gasLimit), GasUsed: int64(gasUsed), Hash: blockHash, + IsFinal: isFinal, + Miner: blockMiner, Nonce: blockNonce, Number: blockNumber, - Miner: blockMiner, ParentHash: blockParentHash, Size: blockSize, Time: int64(blockTime), Transactions: transactions, UncleHash: uncleHash, - IsFinal: isFinal, }, nil } diff --git a/pkg/repositories/testing/helpers.go b/pkg/repositories/testing/helpers.go index e6bc6aa1..7accb32b 100644 --- a/pkg/repositories/testing/helpers.go +++ b/pkg/repositories/testing/helpers.go @@ -62,6 +62,7 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. blockParentHash := "x456" blockNonce := "0x881db2ca900682e9a9" miner := "x123" + extraData := "xextraData" blockTime := int64(1508981640) uncleHash := "x789" blockSize := int64(1000) @@ -71,6 +72,7 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. GasLimit: gasLimit, GasUsed: gasUsed, Hash: blockHash, + ExtraData: extraData, Nonce: blockNonce, Miner: miner, Number: blockNumber, @@ -90,6 +92,7 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. Expect(savedBlock.Hash).To(Equal(blockHash)) Expect(savedBlock.Nonce).To(Equal(blockNonce)) Expect(savedBlock.Miner).To(Equal(miner)) + Expect(savedBlock.ExtraData).To(Equal(extraData)) Expect(savedBlock.Number).To(Equal(blockNumber)) Expect(savedBlock.ParentHash).To(Equal(blockParentHash)) Expect(savedBlock.Size).To(Equal(blockSize)) From 3ca4370221bc2c9dc6fe808eff3bd45e6295157a Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Wed, 27 Dec 2017 17:51:17 -0600 Subject: [PATCH 3/4] Add Block + Uncle Rewards calculation --- integration_test/block_rewards_test.go | 36 ++++++ pkg/core/block.go | 2 + pkg/geth/geth_block_rewards.go | 54 +++++++++ pkg/geth/geth_block_to_core_block.go | 5 + pkg/geth/geth_block_to_core_block_test.go | 128 +++++++++++++++++++++- 5 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 integration_test/block_rewards_test.go create mode 100644 pkg/geth/geth_block_rewards.go diff --git a/integration_test/block_rewards_test.go b/integration_test/block_rewards_test.go new file mode 100644 index 00000000..d183ff92 --- /dev/null +++ b/integration_test/block_rewards_test.go @@ -0,0 +1,36 @@ +package integration + +import ( + "log" + + cfg "github.com/8thlight/vulcanizedb/pkg/config" + "github.com/8thlight/vulcanizedb/pkg/geth" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Reading contracts", func() { + + Describe("Block and Uncle rewards", func() { + It("calculates a block reward for a real block", func() { + config, err := cfg.NewConfig("infura") + if err != nil { + log.Fatalln(err) + } + blockchain := geth.NewGethBlockchain(config.Client.IPCPath) + block := blockchain.GetBlockByNumber(1071819) + Expect(block.BlockReward).To(Equal(5.31355)) + }) + + It("calculates an uncle reward for a real block", func() { + config, err := cfg.NewConfig("infura") + if err != nil { + log.Fatalln(err) + } + blockchain := geth.NewGethBlockchain(config.Client.IPCPath) + block := blockchain.GetBlockByNumber(1071819) + Expect(block.UncleReward).To(Equal(6.875)) + }) + }) + +}) diff --git a/pkg/core/block.go b/pkg/core/block.go index a8300a50..5d78fe1d 100644 --- a/pkg/core/block.go +++ b/pkg/core/block.go @@ -1,6 +1,7 @@ package core type Block struct { + BlockReward float64 Difficulty int64 ExtraData string GasLimit int64 @@ -15,4 +16,5 @@ type Block struct { Time int64 Transactions []Transaction UncleHash string + UncleReward float64 } diff --git a/pkg/geth/geth_block_rewards.go b/pkg/geth/geth_block_rewards.go new file mode 100644 index 00000000..8e4ad79e --- /dev/null +++ b/pkg/geth/geth_block_rewards.go @@ -0,0 +1,54 @@ +package geth + +import ( + "context" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" +) + +func UncleReward(gethBlock *types.Block, client GethClient) float64 { + var uncleReward float64 + for _, uncle := range gethBlock.Uncles() { + staticBlockReward := float64(blockNumberStaticReward(gethBlock)) / float64(8) + uncleReward += float64(uncle.Number.Int64()-gethBlock.Number().Int64()+int64(8)) * staticBlockReward + } + return uncleReward +} + +func BlockReward(gethBlock *types.Block, client GethClient) float64 { + staticBlockReward := blockNumberStaticReward(gethBlock) + transactionFees := calcTransactionFees(gethBlock, client) + uncleInclusionRewards := uncleInclusionRewards(gethBlock, staticBlockReward) + return transactionFees + uncleInclusionRewards + staticBlockReward +} + +func uncleInclusionRewards(gethBlock *types.Block, staticBlockReward float64) float64 { + var uncleInclusionRewards float64 + for range gethBlock.Uncles() { + uncleInclusionRewards += staticBlockReward * 1 / 32 + } + return uncleInclusionRewards +} + +func calcTransactionFees(gethBlock *types.Block, client GethClient) float64 { + var transactionFees float64 + for _, transaction := range gethBlock.Transactions() { + receipt, err := client.TransactionReceipt(context.Background(), transaction.Hash()) + if err != nil { + continue + } + transactionFees += float64(transaction.GasPrice().Int64() * receipt.GasUsed.Int64()) + } + return transactionFees / params.Ether +} + +func blockNumberStaticReward(gethBlock *types.Block) float64 { + var staticBlockReward float64 + if gethBlock.Number().Int64() > 4269999 { + staticBlockReward = 3 + } else { + staticBlockReward = 5 + } + return staticBlockReward +} diff --git a/pkg/geth/geth_block_to_core_block.go b/pkg/geth/geth_block_to_core_block.go index e9895cbd..af307b7a 100644 --- a/pkg/geth/geth_block_to_core_block.go +++ b/pkg/geth/geth_block_to_core_block.go @@ -12,6 +12,7 @@ import ( type GethClient interface { TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) + TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) } func GethBlockToCoreBlock(gethBlock *types.Block, client GethClient) core.Block { @@ -21,6 +22,8 @@ func GethBlockToCoreBlock(gethBlock *types.Block, client GethClient) core.Block transaction := gethTransToCoreTrans(gethTransaction, &from) transactions = append(transactions, transaction) } + blockReward := BlockReward(gethBlock, client) + uncleReward := UncleReward(gethBlock, client) return core.Block{ Difficulty: gethBlock.Difficulty().Int64(), GasLimit: gethBlock.GasLimit().Int64(), @@ -34,7 +37,9 @@ func GethBlockToCoreBlock(gethBlock *types.Block, client GethClient) core.Block Size: gethBlock.Size().Int64(), Time: gethBlock.Time().Int64(), Transactions: transactions, + BlockReward: blockReward, UncleHash: gethBlock.UncleHash().Hex(), + UncleReward: uncleReward, } } diff --git a/pkg/geth/geth_block_to_core_block_test.go b/pkg/geth/geth_block_to_core_block_test.go index 065e6d55..ccf7a85e 100644 --- a/pkg/geth/geth_block_to_core_block_test.go +++ b/pkg/geth/geth_block_to_core_block_test.go @@ -13,7 +13,28 @@ import ( . "github.com/onsi/gomega" ) -type FakeGethClient struct{} +type FakeGethClient struct { + receipts map[string]*types.Receipt +} + +func NewFakeClient() *FakeGethClient { + return &FakeGethClient{ + receipts: make(map[string]*types.Receipt), + } +} + +func (client *FakeGethClient) AddReceipts(receipts []*types.Receipt) { + for _, receipt := range receipts { + client.receipts[receipt.TxHash.Hex()] = receipt + } +} + +func (client *FakeGethClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + if gasUsed, ok := client.receipts[txHash.Hex()]; ok { + return gasUsed, nil + } + return &types.Receipt{GasUsed: big.NewInt(0)}, nil +} func (client *FakeGethClient) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) { return common.HexToAddress("0x123"), nil @@ -62,6 +83,103 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { Expect(gethBlock.IsFinal).To(BeFalse()) }) + Describe("the block and uncle rewards calculations", func() { + It("Calculates block rewards for a block", func() { + number := int64(1071819) + uncles := []*types.Header{{Number: big.NewInt(1071817)}, {Number: big.NewInt(1071818)}} + + nonce := uint64(226823) + to := common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f") + amount := big.NewInt(1080900090000000000) + gasLimit := big.NewInt(90000) + gasPrice := big.NewInt(50000000000) + var payload []byte + transaction := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) + transactions := []*types.Transaction{transaction} + + txHash := transaction.Hash() + receipt := types.Receipt{TxHash: txHash, GasUsed: big.NewInt(21000)} + receipts := []*types.Receipt{&receipt} + + header := types.Header{ + Number: big.NewInt(number), + } + block := types.NewBlock(&header, transactions, uncles, []*types.Receipt{}) + + client := NewFakeClient() + client.AddReceipts(receipts) + + Expect(geth.BlockReward(block, client)).To(Equal(5.31355)) + }) + + It("decreases the static block reward from 5 to 3 for blocks after block 4,269,999", func() { + number := int64(4370055) + var uncles []*types.Header + + nonce := uint64(8072) + to := common.HexToAddress("0xebd17720aeb7ac5186c5dfa7bafeb0bb14c02551 ") + amount := big.NewInt(0) + gasLimit := big.NewInt(500000) + gasPrice := big.NewInt(42000000000) + var payload []byte + transactionOne := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) + + nonce = uint64(8071) + to = common.HexToAddress("0x3cdab63d764c8c5048ed5e8f0a4e95534ba7e1ea") + amount = big.NewInt(0) + gasLimit = big.NewInt(500000) + gasPrice = big.NewInt(42000000000) + transactionTwo := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) + + transactions := []*types.Transaction{transactionOne, transactionTwo} + + txHashOne := transactionOne.Hash() + receiptOne := types.Receipt{TxHash: txHashOne, GasUsed: big.NewInt(297508)} + txHashTwo := transactionTwo.Hash() + receiptTwo := types.Receipt{TxHash: txHashTwo, GasUsed: big.NewInt(297508)} + receipts := []*types.Receipt{&receiptOne, &receiptTwo} + + header := types.Header{ + Number: big.NewInt(number), + } + block := types.NewBlock(&header, transactions, uncles, receipts) + + client := NewFakeClient() + client.AddReceipts(receipts) + + Expect(geth.BlockReward(block, client)).To(Equal(3.024990672)) + }) + + It("Calculates uncle rewards for a block", func() { + number := int64(1071819) + uncles := []*types.Header{{Number: big.NewInt(1071816)}, {Number: big.NewInt(1071817)}} + + nonce := uint64(226823) + to := common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f") + amount := big.NewInt(1080900090000000000) + gasLimit := big.NewInt(90000) + gasPrice := big.NewInt(50000000000) + var payload []byte + transaction := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) + transactions := []*types.Transaction{transaction} + + txHash := transaction.Hash() + receipt := types.Receipt{TxHash: txHash, GasUsed: big.NewInt(21000)} + receipts := []*types.Receipt{&receipt} + + header := types.Header{ + Number: big.NewInt(number), + } + block := types.NewBlock(&header, transactions, uncles, []*types.Receipt{}) + + client := NewFakeClient() + client.AddReceipts(receipts) + + Expect(geth.UncleReward(block, client)).To(Equal(6.875)) + }) + + }) + Describe("the converted transations", func() { It("is empty", func() { header := types.Header{} @@ -72,7 +190,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { Expect(len(coreBlock.Transactions)).To(Equal(0)) }) - It("converts a single transations", func() { + It("converts a single transaction", func() { nonce := uint64(10000) header := types.Header{} to := common.Address{1} @@ -82,7 +200,9 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { payload := []byte("1234") gethTransaction := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) - client := &FakeGethClient{} + + client := NewFakeClient() + gethBlock := types.NewBlock(&header, []*types.Transaction{gethTransaction}, []*types.Header{}, []*types.Receipt{}) coreBlock := geth.GethBlockToCoreBlock(gethBlock, client) @@ -100,8 +220,8 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { It("has an empty to field when transaction creates a new contract", func() { gethTransaction := types.NewContractCreation(uint64(10000), big.NewInt(10), big.NewInt(5000), big.NewInt(3), []byte("1234")) gethBlock := types.NewBlock(&types.Header{}, []*types.Transaction{gethTransaction}, []*types.Header{}, []*types.Receipt{}) - client := &FakeGethClient{} + client := NewFakeClient() coreBlock := geth.GethBlockToCoreBlock(gethBlock, client) coreTransaction := coreBlock.Transactions[0] From 8b024bade9d62837f215f46e1d0f57385b6f1e68 Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Thu, 28 Dec 2017 10:06:13 -0600 Subject: [PATCH 4/4] Add block rewards to db --- ...024_add_block_reward_uncle_reward.down.sql | 3 + ...76024_add_block_reward_uncle_reward.up.sql | 3 + db/schema.sql | 4 +- integration_test/block_rewards_test.go | 38 +++-- pkg/core/block.go | 4 +- pkg/geth/geth_block_rewards.go | 26 ++-- pkg/geth/geth_block_to_core_block.go | 12 +- pkg/geth/geth_block_to_core_block_test.go | 134 +++++++++--------- pkg/repositories/postgres.go | 16 ++- pkg/repositories/testing/helpers.go | 30 ++-- 10 files changed, 149 insertions(+), 121 deletions(-) create mode 100644 db/migrations/1514476024_add_block_reward_uncle_reward.down.sql create mode 100644 db/migrations/1514476024_add_block_reward_uncle_reward.up.sql diff --git a/db/migrations/1514476024_add_block_reward_uncle_reward.down.sql b/db/migrations/1514476024_add_block_reward_uncle_reward.down.sql new file mode 100644 index 00000000..ec96263f --- /dev/null +++ b/db/migrations/1514476024_add_block_reward_uncle_reward.down.sql @@ -0,0 +1,3 @@ +ALTER TABLE blocks + DROP COLUMN block_reward, + DROP COLUMN block_uncles_reward; diff --git a/db/migrations/1514476024_add_block_reward_uncle_reward.up.sql b/db/migrations/1514476024_add_block_reward_uncle_reward.up.sql new file mode 100644 index 00000000..447e53a6 --- /dev/null +++ b/db/migrations/1514476024_add_block_reward_uncle_reward.up.sql @@ -0,0 +1,3 @@ +ALTER TABLE blocks + ADD COLUMN block_reward NUMERIC, + ADD COLUMN block_uncles_reward NUMERIC; diff --git a/db/schema.sql b/db/schema.sql index e4bbce3f..b3eae30a 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -53,7 +53,9 @@ CREATE TABLE blocks ( node_id integer NOT NULL, is_final boolean, block_miner character varying(42), - block_extra_data character varying + block_extra_data character varying, + block_reward numeric, + block_uncles_reward numeric ); diff --git a/integration_test/block_rewards_test.go b/integration_test/block_rewards_test.go index d183ff92..b5ee5351 100644 --- a/integration_test/block_rewards_test.go +++ b/integration_test/block_rewards_test.go @@ -9,28 +9,26 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Reading contracts", func() { +var _ = Describe("Rewards calculations", func() { - Describe("Block and Uncle rewards", func() { - It("calculates a block reward for a real block", func() { - config, err := cfg.NewConfig("infura") - if err != nil { - log.Fatalln(err) - } - blockchain := geth.NewGethBlockchain(config.Client.IPCPath) - block := blockchain.GetBlockByNumber(1071819) - Expect(block.BlockReward).To(Equal(5.31355)) - }) + It("calculates a block reward for a real block", func() { + config, err := cfg.NewConfig("infura") + if err != nil { + log.Fatalln(err) + } + blockchain := geth.NewGethBlockchain(config.Client.IPCPath) + block := blockchain.GetBlockByNumber(1071819) + Expect(block.Reward).To(Equal(5.31355)) + }) - It("calculates an uncle reward for a real block", func() { - config, err := cfg.NewConfig("infura") - if err != nil { - log.Fatalln(err) - } - blockchain := geth.NewGethBlockchain(config.Client.IPCPath) - block := blockchain.GetBlockByNumber(1071819) - Expect(block.UncleReward).To(Equal(6.875)) - }) + It("calculates an uncle reward for a real block", func() { + config, err := cfg.NewConfig("infura") + if err != nil { + log.Fatalln(err) + } + blockchain := geth.NewGethBlockchain(config.Client.IPCPath) + block := blockchain.GetBlockByNumber(1071819) + Expect(block.UnclesReward).To(Equal(6.875)) }) }) diff --git a/pkg/core/block.go b/pkg/core/block.go index 5d78fe1d..d14f43b7 100644 --- a/pkg/core/block.go +++ b/pkg/core/block.go @@ -1,7 +1,7 @@ package core type Block struct { - BlockReward float64 + Reward float64 Difficulty int64 ExtraData string GasLimit int64 @@ -16,5 +16,5 @@ type Block struct { Time int64 Transactions []Transaction UncleHash string - UncleReward float64 + UnclesReward float64 } diff --git a/pkg/geth/geth_block_rewards.go b/pkg/geth/geth_block_rewards.go index 8e4ad79e..f491041d 100644 --- a/pkg/geth/geth_block_rewards.go +++ b/pkg/geth/geth_block_rewards.go @@ -7,24 +7,27 @@ import ( "github.com/ethereum/go-ethereum/params" ) -func UncleReward(gethBlock *types.Block, client GethClient) float64 { - var uncleReward float64 +func CalcUnclesReward(gethBlock *types.Block) float64 { + var unclesReward float64 for _, uncle := range gethBlock.Uncles() { - staticBlockReward := float64(blockNumberStaticReward(gethBlock)) / float64(8) - uncleReward += float64(uncle.Number.Int64()-gethBlock.Number().Int64()+int64(8)) * staticBlockReward + blockNumber := gethBlock.Number().Int64() + staticBlockReward := float64(staticRewardByBlockNumber(blockNumber)) + unclesReward += (1.0 + float64(uncle.Number.Int64()-gethBlock.Number().Int64())/8.0) * staticBlockReward } - return uncleReward + return unclesReward } -func BlockReward(gethBlock *types.Block, client GethClient) float64 { - staticBlockReward := blockNumberStaticReward(gethBlock) +func CalcBlockReward(gethBlock *types.Block, client GethClient) float64 { + blockNumber := gethBlock.Number().Int64() + staticBlockReward := staticRewardByBlockNumber(blockNumber) transactionFees := calcTransactionFees(gethBlock, client) - uncleInclusionRewards := uncleInclusionRewards(gethBlock, staticBlockReward) + uncleInclusionRewards := calcUncleInclusionRewards(gethBlock) return transactionFees + uncleInclusionRewards + staticBlockReward } -func uncleInclusionRewards(gethBlock *types.Block, staticBlockReward float64) float64 { +func calcUncleInclusionRewards(gethBlock *types.Block) float64 { var uncleInclusionRewards float64 + staticBlockReward := staticRewardByBlockNumber(gethBlock.Number().Int64()) for range gethBlock.Uncles() { uncleInclusionRewards += staticBlockReward * 1 / 32 } @@ -43,9 +46,10 @@ func calcTransactionFees(gethBlock *types.Block, client GethClient) float64 { return transactionFees / params.Ether } -func blockNumberStaticReward(gethBlock *types.Block) float64 { +func staticRewardByBlockNumber(blockNumber int64) float64 { var staticBlockReward float64 - if gethBlock.Number().Int64() > 4269999 { + //https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/ + if blockNumber >= 4370000 { staticBlockReward = 3 } else { staticBlockReward = 5 diff --git a/pkg/geth/geth_block_to_core_block.go b/pkg/geth/geth_block_to_core_block.go index af307b7a..ece19b56 100644 --- a/pkg/geth/geth_block_to_core_block.go +++ b/pkg/geth/geth_block_to_core_block.go @@ -22,24 +22,24 @@ func GethBlockToCoreBlock(gethBlock *types.Block, client GethClient) core.Block transaction := gethTransToCoreTrans(gethTransaction, &from) transactions = append(transactions, transaction) } - blockReward := BlockReward(gethBlock, client) - uncleReward := UncleReward(gethBlock, client) + blockReward := CalcBlockReward(gethBlock, client) + uncleReward := CalcUnclesReward(gethBlock) return core.Block{ Difficulty: gethBlock.Difficulty().Int64(), + ExtraData: hexutil.Encode(gethBlock.Extra()), GasLimit: gethBlock.GasLimit().Int64(), GasUsed: gethBlock.GasUsed().Int64(), Hash: gethBlock.Hash().Hex(), - ExtraData: hexutil.Encode(gethBlock.Extra()), + Miner: gethBlock.Coinbase().Hex(), Nonce: hexutil.Encode(gethBlock.Header().Nonce[:]), Number: gethBlock.Number().Int64(), - Miner: gethBlock.Coinbase().Hex(), ParentHash: gethBlock.ParentHash().Hex(), + Reward: blockReward, Size: gethBlock.Size().Int64(), Time: gethBlock.Time().Int64(), Transactions: transactions, - BlockReward: blockReward, UncleHash: gethBlock.UncleHash().Hex(), - UncleReward: uncleReward, + UnclesReward: uncleReward, } } diff --git a/pkg/geth/geth_block_to_core_block_test.go b/pkg/geth/geth_block_to_core_block_test.go index ccf7a85e..5d551a6a 100644 --- a/pkg/geth/geth_block_to_core_block_test.go +++ b/pkg/geth/geth_block_to_core_block_test.go @@ -83,104 +83,110 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() { Expect(gethBlock.IsFinal).To(BeFalse()) }) - Describe("the block and uncle rewards calculations", func() { - It("Calculates block rewards for a block", func() { - number := int64(1071819) - uncles := []*types.Header{{Number: big.NewInt(1071817)}, {Number: big.NewInt(1071818)}} - - nonce := uint64(226823) - to := common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f") - amount := big.NewInt(1080900090000000000) - gasLimit := big.NewInt(90000) - gasPrice := big.NewInt(50000000000) - var payload []byte - transaction := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) + Describe("The block and uncle rewards calculations", func() { + It("calculates block rewards for a block", func() { + transaction := types.NewTransaction( + uint64(226823), + common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f"), + big.NewInt(1080900090000000000), + big.NewInt(90000), + big.NewInt(50000000000), + []byte{}, + ) transactions := []*types.Transaction{transaction} txHash := transaction.Hash() receipt := types.Receipt{TxHash: txHash, GasUsed: big.NewInt(21000)} receipts := []*types.Receipt{&receipt} + number := int64(1071819) header := types.Header{ Number: big.NewInt(number), } + uncles := []*types.Header{{Number: big.NewInt(1071817)}, {Number: big.NewInt(1071818)}} + block := types.NewBlock(&header, transactions, uncles, []*types.Receipt{}) + + client := NewFakeClient() + client.AddReceipts(receipts) + + Expect(geth.CalcBlockReward(block, client)).To(Equal(5.31355)) + }) + + It("calculates the uncles reward for a block", func() { + transaction := types.NewTransaction( + uint64(226823), + common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f"), + big.NewInt(1080900090000000000), + big.NewInt(90000), + big.NewInt(50000000000), + []byte{}) + transactions := []*types.Transaction{transaction} + + receipt := types.Receipt{ + TxHash: transaction.Hash(), + GasUsed: big.NewInt(21000), + } + receipts := []*types.Receipt{&receipt} + + header := types.Header{ + Number: big.NewInt(int64(1071819)), + } + uncles := []*types.Header{ + {Number: big.NewInt(1071816)}, + {Number: big.NewInt(1071817)}, + } block := types.NewBlock(&header, transactions, uncles, []*types.Receipt{}) client := NewFakeClient() client.AddReceipts(receipts) - Expect(geth.BlockReward(block, client)).To(Equal(5.31355)) + Expect(geth.CalcUnclesReward(block)).To(Equal(6.875)) }) It("decreases the static block reward from 5 to 3 for blocks after block 4,269,999", func() { - number := int64(4370055) - var uncles []*types.Header + transactionOne := types.NewTransaction( + uint64(8072), + common.HexToAddress("0xebd17720aeb7ac5186c5dfa7bafeb0bb14c02551 "), + big.NewInt(0), + big.NewInt(500000), + big.NewInt(42000000000), + []byte{}, + ) - nonce := uint64(8072) - to := common.HexToAddress("0xebd17720aeb7ac5186c5dfa7bafeb0bb14c02551 ") - amount := big.NewInt(0) - gasLimit := big.NewInt(500000) - gasPrice := big.NewInt(42000000000) - var payload []byte - transactionOne := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) - - nonce = uint64(8071) - to = common.HexToAddress("0x3cdab63d764c8c5048ed5e8f0a4e95534ba7e1ea") - amount = big.NewInt(0) - gasLimit = big.NewInt(500000) - gasPrice = big.NewInt(42000000000) - transactionTwo := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) + transactionTwo := types.NewTransaction(uint64(8071), + common.HexToAddress("0x3cdab63d764c8c5048ed5e8f0a4e95534ba7e1ea"), + big.NewInt(0), + big.NewInt(500000), + big.NewInt(42000000000), + []byte{}) transactions := []*types.Transaction{transactionOne, transactionTwo} - txHashOne := transactionOne.Hash() - receiptOne := types.Receipt{TxHash: txHashOne, GasUsed: big.NewInt(297508)} - txHashTwo := transactionTwo.Hash() - receiptTwo := types.Receipt{TxHash: txHashTwo, GasUsed: big.NewInt(297508)} + receiptOne := types.Receipt{ + TxHash: transactionOne.Hash(), + GasUsed: big.NewInt(297508), + } + receiptTwo := types.Receipt{ + TxHash: transactionTwo.Hash(), + GasUsed: big.NewInt(297508), + } receipts := []*types.Receipt{&receiptOne, &receiptTwo} + number := int64(4370055) header := types.Header{ Number: big.NewInt(number), } + var uncles []*types.Header block := types.NewBlock(&header, transactions, uncles, receipts) client := NewFakeClient() client.AddReceipts(receipts) - Expect(geth.BlockReward(block, client)).To(Equal(3.024990672)) + Expect(geth.CalcBlockReward(block, client)).To(Equal(3.024990672)) }) - - It("Calculates uncle rewards for a block", func() { - number := int64(1071819) - uncles := []*types.Header{{Number: big.NewInt(1071816)}, {Number: big.NewInt(1071817)}} - - nonce := uint64(226823) - to := common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f") - amount := big.NewInt(1080900090000000000) - gasLimit := big.NewInt(90000) - gasPrice := big.NewInt(50000000000) - var payload []byte - transaction := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, payload) - transactions := []*types.Transaction{transaction} - - txHash := transaction.Hash() - receipt := types.Receipt{TxHash: txHash, GasUsed: big.NewInt(21000)} - receipts := []*types.Receipt{&receipt} - - header := types.Header{ - Number: big.NewInt(number), - } - block := types.NewBlock(&header, transactions, uncles, []*types.Receipt{}) - - client := NewFakeClient() - client.AddReceipts(receipts) - - Expect(geth.UncleReward(block, client)).To(Equal(6.875)) - }) - }) - Describe("the converted transations", func() { + Describe("the converted transactions", func() { It("is empty", func() { header := types.Header{} block := types.NewBlock(&header, []*types.Transaction{}, []*types.Header{}, []*types.Receipt{}) diff --git a/pkg/repositories/postgres.go b/pkg/repositories/postgres.go index ed7446ae..c4b00e5b 100644 --- a/pkg/repositories/postgres.go +++ b/pkg/repositories/postgres.go @@ -200,7 +200,9 @@ func (repository Postgres) FindBlockByNumber(blockNumber int64) (core.Block, err uncle_hash, is_final, block_miner, - block_extra_data + block_extra_data, + block_reward, + block_uncles_reward FROM blocks WHERE node_id = $1 AND block_number = $2`, repository.nodeId, blockNumber) savedBlock, err := repository.loadBlock(blockRows) @@ -258,10 +260,10 @@ func (repository Postgres) insertBlock(block core.Block) error { tx, _ := repository.Db.BeginTx(context.Background(), nil) err := tx.QueryRow( `INSERT INTO blocks - (node_id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash, is_final, block_miner, block_extra_data) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + (node_id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash, is_final, block_miner, block_extra_data, block_reward, block_uncles_reward) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING id `, - repository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal, block.Miner, block.ExtraData). + repository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal, block.Miner, block.ExtraData, block.Reward, block.UnclesReward). Scan(&blockId) if err != nil { tx.Rollback() @@ -312,12 +314,14 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { var blockParentHash string var blockSize int64 var blockTime float64 + var blockReward float64 var difficulty int64 var gasLimit float64 var gasUsed float64 var uncleHash string + var unclesReward float64 var isFinal bool - err := blockRows.Scan(&blockId, &blockNumber, &gasLimit, &gasUsed, &blockTime, &difficulty, &blockHash, &blockNonce, &blockParentHash, &blockSize, &uncleHash, &isFinal, &blockMiner, &blockExtraData) + err := blockRows.Scan(&blockId, &blockNumber, &gasLimit, &gasUsed, &blockTime, &difficulty, &blockHash, &blockNonce, &blockParentHash, &blockSize, &uncleHash, &isFinal, &blockMiner, &blockExtraData, &blockReward, &unclesReward) if err != nil { return core.Block{}, err } @@ -334,6 +338,7 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { ORDER BY tx_hash`, blockId) transactions := repository.loadTransactions(transactionRows) return core.Block{ + Reward: blockReward, Difficulty: difficulty, ExtraData: blockExtraData, GasLimit: int64(gasLimit), @@ -348,6 +353,7 @@ func (repository Postgres) loadBlock(blockRows *sql.Row) (core.Block, error) { Time: int64(blockTime), Transactions: transactions, UncleHash: uncleHash, + UnclesReward: unclesReward, }, nil } diff --git a/pkg/repositories/testing/helpers.go b/pkg/repositories/testing/helpers.go index 7accb32b..ca7420db 100644 --- a/pkg/repositories/testing/helpers.go +++ b/pkg/repositories/testing/helpers.go @@ -67,25 +67,30 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. uncleHash := "x789" blockSize := int64(1000) difficulty := int64(10) + blockReward := float64(5.132) + unclesReward := float64(3.580) block := core.Block{ - Difficulty: difficulty, - GasLimit: gasLimit, - GasUsed: gasUsed, - Hash: blockHash, - ExtraData: extraData, - Nonce: blockNonce, - Miner: miner, - Number: blockNumber, - ParentHash: blockParentHash, - Size: blockSize, - Time: blockTime, - UncleHash: uncleHash, + Reward: blockReward, + Difficulty: difficulty, + GasLimit: gasLimit, + GasUsed: gasUsed, + Hash: blockHash, + ExtraData: extraData, + Nonce: blockNonce, + Miner: miner, + Number: blockNumber, + ParentHash: blockParentHash, + Size: blockSize, + Time: blockTime, + UncleHash: uncleHash, + UnclesReward: unclesReward, } repository.CreateOrUpdateBlock(block) savedBlock, err := repository.FindBlockByNumber(blockNumber) Expect(err).NotTo(HaveOccurred()) + Expect(savedBlock.Reward).To(Equal(blockReward)) Expect(savedBlock.Difficulty).To(Equal(difficulty)) Expect(savedBlock.GasLimit).To(Equal(gasLimit)) Expect(savedBlock.GasUsed).To(Equal(gasUsed)) @@ -98,6 +103,7 @@ func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories. Expect(savedBlock.Size).To(Equal(blockSize)) Expect(savedBlock.Time).To(Equal(blockTime)) Expect(savedBlock.UncleHash).To(Equal(uncleHash)) + Expect(savedBlock.UnclesReward).To(Equal(unclesReward)) }) It("does not find a block when searching for a number that does not exist", func() {