Add block rewards to db
This commit is contained in:
parent
3ca4370221
commit
8b024bade9
@ -0,0 +1,3 @@
|
||||
ALTER TABLE blocks
|
||||
DROP COLUMN block_reward,
|
||||
DROP COLUMN block_uncles_reward;
|
@ -0,0 +1,3 @@
|
||||
ALTER TABLE blocks
|
||||
ADD COLUMN block_reward NUMERIC,
|
||||
ADD COLUMN block_uncles_reward NUMERIC;
|
@ -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
|
||||
);
|
||||
|
||||
|
||||
|
@ -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))
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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{})
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user