Process block rewards and check balances

This commit is contained in:
Alexey Akhunov 2018-06-19 12:32:26 +01:00
parent ee8d406f54
commit f84b84f9cf
4 changed files with 116 additions and 8 deletions

10
Gopkg.lock generated
View File

@ -29,14 +29,22 @@
revision = "346938d642f2ec3594ed81d874461961cd0faa76" revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0" version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/edsrzf/mmap-go"
packages = ["."]
revision = "0bce6a6887123b67a60366d2c9fe2dfb74289d2e"
[[projects]] [[projects]]
name = "github.com/ethereum/go-ethereum" name = "github.com/ethereum/go-ethereum"
packages = [ packages = [
"common", "common",
"common/bitutil",
"common/hexutil", "common/hexutil",
"common/math", "common/math",
"common/mclock", "common/mclock",
"consensus", "consensus",
"consensus/ethash",
"consensus/misc", "consensus/misc",
"core", "core",
"core/rawdb", "core/rawdb",
@ -314,6 +322,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "471d91e2c0a3b0b799ddfd79266deb2f4e6e46a1721f9c00680c370f1eb5662f" inputs-digest = "b5f54632217e0d318d469bb6cd3a30d971c918e4d4bb0165d16603cbab9ba165"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -4,6 +4,6 @@ To build, execute these two commands:
dep ensure dep ensure
go build main.go go build main.go copied.go

42
copied.go Normal file
View File

@ -0,0 +1,42 @@
// Code copied from go-ethereum
package main
import (
"math/big"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/params"
)
// Some weird constants to avoid constant memory allocs for them.
var (
big8 = big.NewInt(8)
big32 = big.NewInt(32)
)
// AccumulateRewards credits the coinbase of the given block with the mining
// reward. The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also rewarded.
func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
// Select the correct block reward based on chain progression
blockReward := ethash.FrontierBlockReward
if config.IsByzantium(header.Number) {
blockReward = ethash.ByzantiumBlockReward
}
// Accumulate the rewards for the miner and any included uncles
reward := new(big.Int).Set(blockReward)
r := new(big.Int)
for _, uncle := range uncles {
r.Add(uncle.Number, big8)
r.Sub(r, header.Number)
r.Mul(r, blockReward)
r.Div(r, big8)
state.AddBalance(uncle.Coinbase, r)
r.Div(blockReward, big32)
reward.Add(reward, r)
}
state.AddBalance(header.Coinbase, reward)
}

70
main.go
View File

@ -3,11 +3,16 @@ package main
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"os"
eth_common "github.com/ethereum/go-ethereum/common" eth_common "github.com/ethereum/go-ethereum/common"
eth_core "github.com/ethereum/go-ethereum/core" eth_core "github.com/ethereum/go-ethereum/core"
eth_state "github.com/ethereum/go-ethereum/core/state" eth_state "github.com/ethereum/go-ethereum/core/state"
eth_types "github.com/ethereum/go-ethereum/core/types"
eth_rlp "github.com/ethereum/go-ethereum/rlp"
eth_ethdb "github.com/ethereum/go-ethereum/ethdb" eth_ethdb "github.com/ethereum/go-ethereum/ethdb"
eth_params "github.com/ethereum/go-ethereum/params"
eth_trie "github.com/ethereum/go-ethereum/trie" eth_trie "github.com/ethereum/go-ethereum/trie"
dbm "github.com/tendermint/tmlibs/db" dbm "github.com/tendermint/tmlibs/db"
@ -208,16 +213,69 @@ func main() {
// One of the genesis account having 200 ETH // One of the genesis account having 200 ETH
b := statedb.GetBalance(eth_common.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0")) b := statedb.GetBalance(eth_common.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0"))
fmt.Printf("Balance: %s\n", b) fmt.Printf("Balance: %s\n", b)
root, err := statedb.Commit(false /* deleteEmptyObjects */) genesis_root, err := statedb.Commit(false /* deleteEmptyObjects */)
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Printf("Genesis state root hash: %x\n", root[:]) fmt.Printf("Genesis state root hash: %x\n", genesis_root[:])
// Try to create a new statedb from genesis hash // File with blockchain data exported from geth by using "geth expordb" command
genesis_state, err := eth_state.New(root, d) input, err := os.Open("/Users/alexeyakhunov/mygit/blockchain")
if err != nil { if err != nil {
panic(err) panic(err)
} }
b1 := genesis_state.GetBalance(eth_common.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0")) defer input.Close()
fmt.Printf("Balance reloaded: %s\n", b1) // Ethereum mainnet config
chainConfig := eth_params.MainnetChainConfig
stream := eth_rlp.NewStream(input, 0)
var block eth_types.Block
n := 0
var root500 eth_common.Hash // Root hash after block 500
var root501 eth_common.Hash // Root hash after block 501
for {
if err = stream.Decode(&block); err == io.EOF {
err = nil // Clear it
break
} else if err != nil {
panic(fmt.Errorf("at block %d: %v", n, err))
}
// don't import first block
if block.NumberU64() == 0 {
continue
}
header := block.Header()
// Apply mining rewards to the statedb
accumulateRewards(chainConfig, statedb, header, block.Uncles())
// Commit block
root, err := statedb.Commit(chainConfig.IsEIP158(block.Number()) /* deleteEmptyObjects */)
if err != nil {
panic(err)
}
switch n {
case 500:
root500 = root
case 501:
root501 = root
}
n++
if n >= 1000 {
break
}
}
fmt.Printf("Processed %d blocks\n", n)
genesis_state, err := eth_state.New(genesis_root, d)
fmt.Printf("Balance of one of the genesis investors: %s\n", genesis_state.GetBalance(eth_common.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0")))
miner501 := eth_common.HexToAddress("0x35e8e5dC5FBd97c5b421A80B596C030a2Be2A04D") // Miner of the block 501
// Try to create a new statedb from root of the block 500
state500, err := eth_state.New(root500, d)
if err != nil {
panic(err)
}
miner501_balance_at_500 := state500.GetBalance(miner501)
state501, err := eth_state.New(root501, d)
if err != nil {
panic(err)
}
miner501_balance_at_501 := state501.GetBalance(miner501)
fmt.Printf("Miner of block 501's balance after block 500: %d\n", miner501_balance_at_500)
fmt.Printf("Miner of block 501's balance after block 501: %d\n", miner501_balance_at_501)
} }