forked from cerc-io/plugeth
Refactored block & Transaction
* Includes new rlp decoder
This commit is contained in:
parent
4b52cd512d
commit
4cd79d8ddd
@ -86,12 +86,6 @@ func (self *JSRepl) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *JSRepl) parseInput(code string) {
|
func (self *JSRepl) parseInput(code string) {
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
fmt.Println("[native] error", r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
value, err := self.re.Run(code)
|
value, err := self.re.Run(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
@ -325,7 +325,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
|
|||||||
return fmt.Errorf("unknown block %x", hash)
|
return fmt.Errorf("unknown block %x", hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
parent := ethereum.ChainManager().GetBlock(block.PrevHash)
|
parent := ethereum.ChainManager().GetBlock(block.ParentHash())
|
||||||
|
|
||||||
_, err := ethereum.BlockManager().TransitionState(parent.State(), parent, block)
|
_, err := ethereum.BlockManager().TransitionState(parent.State(), parent, block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -30,15 +30,15 @@ func NewEnv(state *state.StateDB, block *types.Block, transactor []byte, value *
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Origin() []byte { return self.transactor }
|
func (self *VMEnv) Origin() []byte { return self.transactor }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
|
||||||
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
|
func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
|
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time }
|
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
||||||
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
||||||
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.value }
|
func (self *VMEnv) Value() *big.Int { return self.value }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
||||||
func (self *VMEnv) AddLog(log state.Log) {
|
func (self *VMEnv) AddLog(log state.Log) {
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/pow/ezp"
|
"github.com/ethereum/go-ethereum/pow/ezp"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
|
"gopkg.in/fatih/set.v0"
|
||||||
)
|
)
|
||||||
|
|
||||||
var statelogger = logger.NewLogger("BLOCK")
|
var statelogger = logger.NewLogger("BLOCK")
|
||||||
@ -82,8 +83,8 @@ func NewBlockManager(txpool *TxPool, chainManager *ChainManager, eventMux *event
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) {
|
func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) {
|
||||||
coinbase := statedb.GetOrNewStateObject(block.Coinbase)
|
coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase)
|
||||||
coinbase.SetGasPool(block.CalcGasLimit(parent))
|
coinbase.SetGasPool(CalcGasLimit(parent, block))
|
||||||
|
|
||||||
// Process the transactions on to current block
|
// Process the transactions on to current block
|
||||||
receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false)
|
receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false)
|
||||||
@ -156,7 +157,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
block.Reward = cumulativeSum
|
block.Reward = cumulativeSum
|
||||||
block.GasUsed = totalUsedGas
|
block.Header().GasUsed = totalUsedGas
|
||||||
|
|
||||||
return receipts, handled, unhandled, erroneous, err
|
return receipts, handled, unhandled, erroneous, err
|
||||||
}
|
}
|
||||||
@ -166,14 +167,15 @@ func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Mes
|
|||||||
sm.mutex.Lock()
|
sm.mutex.Lock()
|
||||||
defer sm.mutex.Unlock()
|
defer sm.mutex.Unlock()
|
||||||
|
|
||||||
if sm.bc.HasBlock(block.Hash()) {
|
header := block.Header()
|
||||||
return nil, nil, &KnownBlockError{block.Number, block.Hash()}
|
if sm.bc.HasBlock(header.Hash()) {
|
||||||
|
return nil, nil, &KnownBlockError{header.Number, header.Hash()}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sm.bc.HasBlock(block.PrevHash) {
|
if !sm.bc.HasBlock(header.ParentHash) {
|
||||||
return nil, nil, ParentError(block.PrevHash)
|
return nil, nil, ParentError(header.ParentHash)
|
||||||
}
|
}
|
||||||
parent := sm.bc.GetBlock(block.PrevHash)
|
parent := sm.bc.GetBlock(header.ParentHash)
|
||||||
|
|
||||||
return sm.ProcessWithParent(block, parent)
|
return sm.ProcessWithParent(block, parent)
|
||||||
}
|
}
|
||||||
@ -181,7 +183,7 @@ func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Mes
|
|||||||
func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
|
func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
|
||||||
sm.lastAttemptedBlock = block
|
sm.lastAttemptedBlock = block
|
||||||
|
|
||||||
state := parent.State().Copy()
|
state := state.New(parent.Trie().Copy())
|
||||||
|
|
||||||
// Defer the Undo on the Trie. If the block processing happened
|
// Defer the Undo on the Trie. If the block processing happened
|
||||||
// we don't want to undo but since undo only happens on dirty
|
// we don't want to undo but since undo only happens on dirty
|
||||||
@ -199,23 +201,23 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header := block.Header()
|
||||||
|
|
||||||
rbloom := types.CreateBloom(receipts)
|
rbloom := types.CreateBloom(receipts)
|
||||||
if bytes.Compare(rbloom, block.LogsBloom) != 0 {
|
if bytes.Compare(rbloom, header.Bloom) != 0 {
|
||||||
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
|
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
txSha := types.DeriveSha(block.Transactions())
|
txSha := types.DeriveSha(block.Transactions())
|
||||||
if bytes.Compare(txSha, block.TxSha) != 0 {
|
if bytes.Compare(txSha, header.TxHash) != 0 {
|
||||||
err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
|
err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
receiptSha := types.DeriveSha(receipts)
|
receiptSha := types.DeriveSha(receipts)
|
||||||
if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
|
if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
|
||||||
//chainlogger.Debugf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
|
err = fmt.Errorf("validating receipt root. received=%x got=%x", header.ReceiptHash, receiptSha)
|
||||||
fmt.Printf("%x\n", ethutil.Encode(receipts))
|
|
||||||
err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,8 +227,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
|
|||||||
|
|
||||||
state.Update(ethutil.Big0)
|
state.Update(ethutil.Big0)
|
||||||
|
|
||||||
if !block.State().Cmp(state) {
|
if !bytes.Equal(header.Root, state.Root()) {
|
||||||
err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root())
|
err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +240,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
|
|||||||
messages := state.Manifest().Messages
|
messages := state.Manifest().Messages
|
||||||
state.Manifest().Reset()
|
state.Manifest().Reset()
|
||||||
|
|
||||||
chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4])
|
chainlogger.Infof("Processed block #%d (%x...)\n", header.Number, block.Hash()[0:4])
|
||||||
|
|
||||||
sm.txpool.RemoveSet(block.Transactions())
|
sm.txpool.RemoveSet(block.Transactions())
|
||||||
|
|
||||||
@ -250,14 +252,14 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
|
|||||||
|
|
||||||
func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
|
func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
|
||||||
uncleDiff := new(big.Int)
|
uncleDiff := new(big.Int)
|
||||||
for _, uncle := range block.Uncles {
|
for _, uncle := range block.Uncles() {
|
||||||
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
|
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
|
// TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
|
||||||
td := new(big.Int)
|
td := new(big.Int)
|
||||||
td = td.Add(sm.bc.Td(), uncleDiff)
|
td = td.Add(sm.bc.Td(), uncleDiff)
|
||||||
td = td.Add(td, block.Difficulty)
|
td = td.Add(td, block.Header().Difficulty)
|
||||||
|
|
||||||
// The new TD will only be accepted if the new difficulty is
|
// The new TD will only be accepted if the new difficulty is
|
||||||
// is greater than the previous.
|
// is greater than the previous.
|
||||||
@ -273,13 +275,13 @@ func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
|
|||||||
// Validation validates easy over difficult (dagger takes longer time = difficult)
|
// Validation validates easy over difficult (dagger takes longer time = difficult)
|
||||||
func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
|
func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
|
||||||
expd := CalcDifficulty(block, parent)
|
expd := CalcDifficulty(block, parent)
|
||||||
if expd.Cmp(block.Difficulty) < 0 {
|
if expd.Cmp(block.Header().Difficulty) < 0 {
|
||||||
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
|
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd)
|
||||||
}
|
}
|
||||||
|
|
||||||
diff := block.Time - parent.Time
|
diff := block.Header().Time - parent.Header().Time
|
||||||
if diff < 0 {
|
if diff < 0 {
|
||||||
return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock().Time)
|
return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Header().Time, sm.bc.CurrentBlock().Header().Time)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX
|
/* XXX
|
||||||
@ -291,7 +293,7 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
|
|||||||
|
|
||||||
// Verify the nonce of the block. Return an error if it's not valid
|
// Verify the nonce of the block. Return an error if it's not valid
|
||||||
if !sm.Pow.Verify(block /*block.HashNoNonce(), block.Difficulty, block.Nonce*/) {
|
if !sm.Pow.Verify(block /*block.HashNoNonce(), block.Difficulty, block.Nonce*/) {
|
||||||
return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce))
|
return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Header().Nonce))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -300,24 +302,28 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
|
|||||||
func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent *types.Block) error {
|
func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent *types.Block) error {
|
||||||
reward := new(big.Int).Set(BlockReward)
|
reward := new(big.Int).Set(BlockReward)
|
||||||
|
|
||||||
knownUncles := ethutil.Set(parent.Uncles)
|
knownUncles := set.New()
|
||||||
nonces := ethutil.NewSet(block.Nonce)
|
for _, uncle := range parent.Uncles() {
|
||||||
for _, uncle := range block.Uncles {
|
knownUncles.Add(uncle.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
nonces := ethutil.NewSet(block.Header().Nonce)
|
||||||
|
for _, uncle := range block.Uncles() {
|
||||||
if nonces.Include(uncle.Nonce) {
|
if nonces.Include(uncle.Nonce) {
|
||||||
// Error not unique
|
// Error not unique
|
||||||
return UncleError("Uncle not unique")
|
return UncleError("Uncle not unique")
|
||||||
}
|
}
|
||||||
|
|
||||||
uncleParent := sm.bc.GetBlock(uncle.PrevHash)
|
uncleParent := sm.bc.GetBlock(uncle.ParentHash)
|
||||||
if uncleParent == nil {
|
if uncleParent == nil {
|
||||||
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.PrevHash[0:4]))
|
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
|
||||||
}
|
}
|
||||||
|
|
||||||
if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 {
|
if uncleParent.Header().Number.Cmp(new(big.Int).Sub(parent.Header().Number, big.NewInt(6))) < 0 {
|
||||||
return UncleError("Uncle too old")
|
return UncleError("Uncle too old")
|
||||||
}
|
}
|
||||||
|
|
||||||
if knownUncles.Include(uncle.Hash()) {
|
if knownUncles.Has(uncle.Hash()) {
|
||||||
return UncleError("Uncle in chain")
|
return UncleError("Uncle in chain")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,15 +339,15 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the account associated with the coinbase
|
// Get the account associated with the coinbase
|
||||||
account := statedb.GetAccount(block.Coinbase)
|
account := statedb.GetAccount(block.Header().Coinbase)
|
||||||
// Reward amount of ether to the coinbase address
|
// Reward amount of ether to the coinbase address
|
||||||
account.AddAmount(reward)
|
account.AddAmount(reward)
|
||||||
|
|
||||||
statedb.Manifest().AddMessage(&state.Message{
|
statedb.Manifest().AddMessage(&state.Message{
|
||||||
To: block.Coinbase,
|
To: block.Header().Coinbase,
|
||||||
Input: nil,
|
Input: nil,
|
||||||
Origin: nil,
|
Origin: nil,
|
||||||
Block: block.Hash(), Timestamp: block.Time, Coinbase: block.Coinbase, Number: block.Number,
|
Block: block.Hash(), Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
|
||||||
Value: new(big.Int).Add(reward, block.Reward),
|
Value: new(big.Int).Add(reward, block.Reward),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -349,15 +355,15 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Message, err error) {
|
func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Message, err error) {
|
||||||
if !sm.bc.HasBlock(block.PrevHash) {
|
if !sm.bc.HasBlock(block.Header().ParentHash) {
|
||||||
return nil, ParentError(block.PrevHash)
|
return nil, ParentError(block.Header().ParentHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
sm.lastAttemptedBlock = block
|
sm.lastAttemptedBlock = block
|
||||||
|
|
||||||
var (
|
var (
|
||||||
parent = sm.bc.GetBlock(block.PrevHash)
|
parent = sm.bc.GetBlock(block.Header().ParentHash)
|
||||||
state = parent.State().Copy()
|
state = state.New(parent.Trie().Copy())
|
||||||
)
|
)
|
||||||
|
|
||||||
defer state.Reset()
|
defer state.Reset()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
@ -9,11 +10,13 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var chainlogger = logger.NewLogger("CHAIN")
|
var chainlogger = logger.NewLogger("CHAIN")
|
||||||
|
|
||||||
|
/*
|
||||||
func AddTestNetFunds(block *types.Block) {
|
func AddTestNetFunds(block *types.Block) {
|
||||||
for _, addr := range []string{
|
for _, addr := range []string{
|
||||||
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
|
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
|
||||||
@ -31,20 +34,41 @@ func AddTestNetFunds(block *types.Block) {
|
|||||||
block.State().UpdateStateObject(account)
|
block.State().UpdateStateObject(account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func CalcDifficulty(block, parent *types.Block) *big.Int {
|
func CalcDifficulty(block, parent *types.Block) *big.Int {
|
||||||
diff := new(big.Int)
|
diff := new(big.Int)
|
||||||
|
|
||||||
adjust := new(big.Int).Rsh(parent.Difficulty, 10)
|
bh, ph := block.Header(), parent.Header()
|
||||||
if block.Time >= parent.Time+5 {
|
adjust := new(big.Int).Rsh(ph.Difficulty, 10)
|
||||||
diff.Sub(parent.Difficulty, adjust)
|
if bh.Time >= ph.Time+5 {
|
||||||
|
diff.Sub(ph.Difficulty, adjust)
|
||||||
} else {
|
} else {
|
||||||
diff.Add(parent.Difficulty, adjust)
|
diff.Add(ph.Difficulty, adjust)
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CalcGasLimit(parent, block *types.Block) *big.Int {
|
||||||
|
if block.Number().Cmp(big.NewInt(0)) == 0 {
|
||||||
|
return ethutil.BigPow(10, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024
|
||||||
|
|
||||||
|
previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit())
|
||||||
|
current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed()), big.NewRat(6, 5))
|
||||||
|
curInt := new(big.Int).Div(current.Num(), current.Denom())
|
||||||
|
|
||||||
|
result := new(big.Int).Add(previous, curInt)
|
||||||
|
result.Div(result, big.NewInt(1024))
|
||||||
|
|
||||||
|
min := big.NewInt(125000)
|
||||||
|
|
||||||
|
return ethutil.BigMax(min, result)
|
||||||
|
}
|
||||||
|
|
||||||
type ChainManager struct {
|
type ChainManager struct {
|
||||||
//eth EthManager
|
//eth EthManager
|
||||||
processor types.BlockProcessor
|
processor types.BlockProcessor
|
||||||
@ -90,7 +114,7 @@ func (self *ChainManager) CurrentBlock() *types.Block {
|
|||||||
|
|
||||||
func NewChainManager(mux *event.TypeMux) *ChainManager {
|
func NewChainManager(mux *event.TypeMux) *ChainManager {
|
||||||
bc := &ChainManager{}
|
bc := &ChainManager{}
|
||||||
bc.genesisBlock = types.NewBlockFromBytes(ethutil.Encode(Genesis))
|
bc.genesisBlock = GenesisBlock()
|
||||||
bc.eventMux = mux
|
bc.eventMux = mux
|
||||||
|
|
||||||
bc.setLastBlock()
|
bc.setLastBlock()
|
||||||
@ -112,7 +136,7 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *ChainManager) State() *state.StateDB {
|
func (self *ChainManager) State() *state.StateDB {
|
||||||
return self.CurrentBlock().State()
|
return state.New(self.CurrentBlock().Trie())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ChainManager) TransState() *state.StateDB {
|
func (self *ChainManager) TransState() *state.StateDB {
|
||||||
@ -122,13 +146,11 @@ func (self *ChainManager) TransState() *state.StateDB {
|
|||||||
func (bc *ChainManager) setLastBlock() {
|
func (bc *ChainManager) setLastBlock() {
|
||||||
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
|
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
|
||||||
if len(data) != 0 {
|
if len(data) != 0 {
|
||||||
// Prep genesis
|
var block types.Block
|
||||||
AddTestNetFunds(bc.genesisBlock)
|
rlp.Decode(bytes.NewReader(data), &block)
|
||||||
|
bc.currentBlock = &block
|
||||||
block := types.NewBlockFromBytes(data)
|
|
||||||
bc.currentBlock = block
|
|
||||||
bc.lastBlockHash = block.Hash()
|
bc.lastBlockHash = block.Hash()
|
||||||
bc.lastBlockNumber = block.Number.Uint64()
|
bc.lastBlockNumber = block.Header().Number.Uint64()
|
||||||
|
|
||||||
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
|
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
|
||||||
bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
|
bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
|
||||||
@ -144,27 +166,28 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
|
|||||||
bc.mu.RLock()
|
bc.mu.RLock()
|
||||||
defer bc.mu.RUnlock()
|
defer bc.mu.RUnlock()
|
||||||
|
|
||||||
var root interface{}
|
var root []byte
|
||||||
hash := ZeroHash256
|
parentHash := ZeroHash256
|
||||||
|
|
||||||
if bc.CurrentBlock != nil {
|
if bc.CurrentBlock != nil {
|
||||||
root = bc.currentBlock.Root()
|
root = bc.currentBlock.Header().Root
|
||||||
hash = bc.lastBlockHash
|
parentHash = bc.lastBlockHash
|
||||||
}
|
}
|
||||||
|
|
||||||
block := types.CreateBlock(
|
block := types.NewBlock(
|
||||||
root,
|
parentHash,
|
||||||
hash,
|
|
||||||
coinbase,
|
coinbase,
|
||||||
|
root,
|
||||||
ethutil.BigPow(2, 32),
|
ethutil.BigPow(2, 32),
|
||||||
nil,
|
nil,
|
||||||
"")
|
"")
|
||||||
|
|
||||||
parent := bc.currentBlock
|
parent := bc.currentBlock
|
||||||
if parent != nil {
|
if parent != nil {
|
||||||
block.Difficulty = CalcDifficulty(block, parent)
|
header := block.Header()
|
||||||
block.Number = new(big.Int).Add(bc.currentBlock.Number, ethutil.Big1)
|
header.Difficulty = CalcDifficulty(block, parent)
|
||||||
block.GasLimit = block.CalcGasLimit(bc.currentBlock)
|
header.Number = new(big.Int).Add(parent.Header().Number, ethutil.Big1)
|
||||||
|
header.GasLimit = CalcGasLimit(parent, block)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,9 +198,6 @@ func (bc *ChainManager) Reset() {
|
|||||||
bc.mu.Lock()
|
bc.mu.Lock()
|
||||||
defer bc.mu.Unlock()
|
defer bc.mu.Unlock()
|
||||||
|
|
||||||
AddTestNetFunds(bc.genesisBlock)
|
|
||||||
|
|
||||||
bc.genesisBlock.Trie().Sync()
|
|
||||||
// Prepare the genesis block
|
// Prepare the genesis block
|
||||||
bc.write(bc.genesisBlock)
|
bc.write(bc.genesisBlock)
|
||||||
bc.insert(bc.genesisBlock)
|
bc.insert(bc.genesisBlock)
|
||||||
@ -193,18 +213,20 @@ func (self *ChainManager) Export() []byte {
|
|||||||
self.mu.RLock()
|
self.mu.RLock()
|
||||||
defer self.mu.RUnlock()
|
defer self.mu.RUnlock()
|
||||||
|
|
||||||
chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Number)
|
chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Header().Number)
|
||||||
|
|
||||||
blocks := make([]*types.Block, int(self.currentBlock.Number.Int64())+1)
|
blocks := make([]*types.Block, int(self.currentBlock.NumberU64())+1)
|
||||||
for block := self.currentBlock; block != nil; block = self.GetBlock(block.PrevHash) {
|
for block := self.currentBlock; block != nil; block = self.GetBlock(block.Header().ParentHash) {
|
||||||
blocks[block.Number.Int64()] = block
|
blocks[block.NumberU64()] = block
|
||||||
}
|
}
|
||||||
|
//fmt.Println(blocks)
|
||||||
|
|
||||||
|
return nil
|
||||||
return ethutil.Encode(blocks)
|
return ethutil.Encode(blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *ChainManager) insert(block *types.Block) {
|
func (bc *ChainManager) insert(block *types.Block) {
|
||||||
encodedBlock := block.RlpEncode()
|
encodedBlock := ethutil.Encode(block)
|
||||||
ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
|
ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
|
||||||
bc.currentBlock = block
|
bc.currentBlock = block
|
||||||
bc.lastBlockHash = block.Hash()
|
bc.lastBlockHash = block.Hash()
|
||||||
@ -213,7 +235,7 @@ func (bc *ChainManager) insert(block *types.Block) {
|
|||||||
func (bc *ChainManager) write(block *types.Block) {
|
func (bc *ChainManager) write(block *types.Block) {
|
||||||
bc.writeBlockInfo(block)
|
bc.writeBlockInfo(block)
|
||||||
|
|
||||||
encodedBlock := block.RlpEncode()
|
encodedBlock := ethutil.Encode(block)
|
||||||
ethutil.Config.Db.Put(block.Hash(), encodedBlock)
|
ethutil.Config.Db.Put(block.Hash(), encodedBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,11 +260,11 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain
|
|||||||
for i := uint64(0); i < max; i++ {
|
for i := uint64(0); i < max; i++ {
|
||||||
chain = append(chain, block.Hash())
|
chain = append(chain, block.Hash())
|
||||||
|
|
||||||
if block.Number.Cmp(ethutil.Big0) <= 0 {
|
if block.Header().Number.Cmp(ethutil.Big0) <= 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
block = self.GetBlock(block.PrevHash)
|
block = self.GetBlock(block.Header().ParentHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -253,8 +275,13 @@ func (self *ChainManager) GetBlock(hash []byte) *types.Block {
|
|||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
var block types.Block
|
||||||
|
if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return types.NewBlockFromBytes(data)
|
return &block
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
|
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
|
||||||
@ -262,13 +289,13 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
|
|||||||
defer self.mu.RUnlock()
|
defer self.mu.RUnlock()
|
||||||
|
|
||||||
block := self.currentBlock
|
block := self.currentBlock
|
||||||
for ; block != nil; block = self.GetBlock(block.PrevHash) {
|
for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
|
||||||
if block.Number.Uint64() == num {
|
if block.Header().Number.Uint64() == num {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if block != nil && block.Number.Uint64() == 0 && num != 0 {
|
if block != nil && block.Header().Number.Uint64() == 0 && num != 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,40 +308,28 @@ func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
|
func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
|
||||||
parent := self.GetBlock(block.PrevHash)
|
parent := self.GetBlock(block.Header().ParentHash)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return nil, fmt.Errorf("Unable to calculate total diff without known parent %x", block.PrevHash)
|
return nil, fmt.Errorf("Unable to calculate total diff without known parent %x", block.Header().ParentHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
parentTd := parent.BlockInfo().TD
|
parentTd := parent.Td
|
||||||
|
|
||||||
uncleDiff := new(big.Int)
|
uncleDiff := new(big.Int)
|
||||||
for _, uncle := range block.Uncles {
|
for _, uncle := range block.Uncles() {
|
||||||
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
|
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
|
||||||
}
|
}
|
||||||
|
|
||||||
td := new(big.Int)
|
td := new(big.Int)
|
||||||
td = td.Add(parentTd, uncleDiff)
|
td = td.Add(parentTd, uncleDiff)
|
||||||
td = td.Add(td, block.Difficulty)
|
td = td.Add(td, block.Header().Difficulty)
|
||||||
|
|
||||||
return td, nil
|
return td, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *ChainManager) BlockInfo(block *types.Block) types.BlockInfo {
|
|
||||||
bi := types.BlockInfo{}
|
|
||||||
data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...))
|
|
||||||
bi.RlpDecode(data)
|
|
||||||
|
|
||||||
return bi
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unexported method for writing extra non-essential block info to the db
|
// Unexported method for writing extra non-essential block info to the db
|
||||||
func (bc *ChainManager) writeBlockInfo(block *types.Block) {
|
func (bc *ChainManager) writeBlockInfo(block *types.Block) {
|
||||||
bc.lastBlockNumber++
|
bc.lastBlockNumber++
|
||||||
bi := types.BlockInfo{Number: bc.lastBlockNumber, Hash: block.Hash(), Parent: block.PrevHash, TD: bc.td}
|
|
||||||
|
|
||||||
// For now we use the block hash with the words "info" appended as key
|
|
||||||
ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.RlpEncode())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *ChainManager) Stop() {
|
func (bc *ChainManager) Stop() {
|
||||||
@ -331,7 +346,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
chainlogger.Infof("block #%v process failed (%x)\n", block.Number, block.Hash()[:4])
|
h := block.Header()
|
||||||
|
chainlogger.Infof("block #%v process failed (%x)\n", h.Number, h.Hash()[:4])
|
||||||
chainlogger.Infoln(block)
|
chainlogger.Infoln(block)
|
||||||
chainlogger.Infoln(err)
|
chainlogger.Infoln(err)
|
||||||
return err
|
return err
|
||||||
@ -339,16 +355,16 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
|
|||||||
|
|
||||||
self.mu.Lock()
|
self.mu.Lock()
|
||||||
{
|
{
|
||||||
|
|
||||||
self.write(block)
|
self.write(block)
|
||||||
|
cblock := self.currentBlock
|
||||||
if td.Cmp(self.td) > 0 {
|
if td.Cmp(self.td) > 0 {
|
||||||
if block.Number.Cmp(new(big.Int).Add(self.currentBlock.Number, ethutil.Big1)) < 0 {
|
if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, ethutil.Big1)) < 0 {
|
||||||
chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Number, block.Hash()[:4], self.currentBlock.Number, self.currentBlock.Hash()[:4])
|
chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Header().Number, block.Hash()[:4], cblock.Header().Number, cblock.Hash()[:4])
|
||||||
}
|
}
|
||||||
|
|
||||||
self.setTotalDifficulty(td)
|
self.setTotalDifficulty(td)
|
||||||
self.insert(block)
|
self.insert(block)
|
||||||
self.transState = self.currentBlock.State().Copy()
|
self.transState = state.New(cblock.Trie().Copy())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -76,13 +76,14 @@ func (self *Filter) SetSkip(skip int) {
|
|||||||
|
|
||||||
// Run filters messages with the current parameters set
|
// Run filters messages with the current parameters set
|
||||||
func (self *Filter) Find() []*state.Message {
|
func (self *Filter) Find() []*state.Message {
|
||||||
|
earliestBlock := self.eth.ChainManager().CurrentBlock()
|
||||||
var earliestBlockNo uint64 = uint64(self.earliest)
|
var earliestBlockNo uint64 = uint64(self.earliest)
|
||||||
if self.earliest == -1 {
|
if self.earliest == -1 {
|
||||||
earliestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
|
earliestBlockNo = earliestBlock.NumberU64()
|
||||||
}
|
}
|
||||||
var latestBlockNo uint64 = uint64(self.latest)
|
var latestBlockNo uint64 = uint64(self.latest)
|
||||||
if self.latest == -1 {
|
if self.latest == -1 {
|
||||||
latestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
|
latestBlockNo = earliestBlock.NumberU64()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -93,7 +94,7 @@ func (self *Filter) Find() []*state.Message {
|
|||||||
for i := 0; !quit && block != nil; i++ {
|
for i := 0; !quit && block != nil; i++ {
|
||||||
// Quit on latest
|
// Quit on latest
|
||||||
switch {
|
switch {
|
||||||
case block.Number.Uint64() == earliestBlockNo, block.Number.Uint64() == 0:
|
case block.NumberU64() == earliestBlockNo, block.NumberU64() == 0:
|
||||||
quit = true
|
quit = true
|
||||||
case self.max <= len(messages):
|
case self.max <= len(messages):
|
||||||
break
|
break
|
||||||
@ -113,7 +114,7 @@ func (self *Filter) Find() []*state.Message {
|
|||||||
messages = append(messages, self.FilterMessages(msgs)...)
|
messages = append(messages, self.FilterMessages(msgs)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
block = self.eth.ChainManager().GetBlock(block.PrevHash)
|
block = self.eth.ChainManager().GetBlock(block.ParentHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
skip := int(math.Min(float64(len(messages)), float64(self.skip)))
|
skip := int(math.Min(float64(len(messages)), float64(self.skip)))
|
||||||
@ -176,7 +177,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
|
|||||||
var fromIncluded, toIncluded bool
|
var fromIncluded, toIncluded bool
|
||||||
if len(self.from) > 0 {
|
if len(self.from) > 0 {
|
||||||
for _, from := range self.from {
|
for _, from := range self.from {
|
||||||
if types.BloomLookup(block.LogsBloom, from) || bytes.Equal(block.Coinbase, from) {
|
if types.BloomLookup(block.Bloom(), from) || bytes.Equal(block.Coinbase(), from) {
|
||||||
fromIncluded = true
|
fromIncluded = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -187,7 +188,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
|
|||||||
|
|
||||||
if len(self.to) > 0 {
|
if len(self.to) > 0 {
|
||||||
for _, to := range self.to {
|
for _, to := range self.to {
|
||||||
if types.BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) || bytes.Equal(block.Coinbase, to) {
|
if types.BloomLookup(block.Bloom(), ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) || bytes.Equal(block.Coinbase(), to) {
|
||||||
toIncluded = true
|
toIncluded = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ package core
|
|||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
|
"github.com/ethereum/go-ethereum/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -17,36 +19,35 @@ var ZeroHash512 = make([]byte, 64)
|
|||||||
var EmptyShaList = crypto.Sha3(ethutil.Encode([]interface{}{}))
|
var EmptyShaList = crypto.Sha3(ethutil.Encode([]interface{}{}))
|
||||||
var EmptyListRoot = crypto.Sha3(ethutil.Encode(""))
|
var EmptyListRoot = crypto.Sha3(ethutil.Encode(""))
|
||||||
|
|
||||||
var GenesisHeader = []interface{}{
|
func GenesisBlock() *types.Block {
|
||||||
// Previous hash (none)
|
genesis := types.NewBlock(ZeroHash256, ZeroHash160, EmptyListRoot, big.NewInt(131072), crypto.Sha3(big.NewInt(42).Bytes()), "")
|
||||||
ZeroHash256,
|
genesis.Header().Number = ethutil.Big0
|
||||||
// Empty uncles
|
genesis.Header().GasLimit = big.NewInt(1000000)
|
||||||
EmptyShaList,
|
genesis.Header().GasUsed = ethutil.Big0
|
||||||
// Coinbase
|
genesis.Header().Time = 0
|
||||||
ZeroHash160,
|
|
||||||
// Root state
|
|
||||||
EmptyShaList,
|
|
||||||
// tx root
|
|
||||||
EmptyListRoot,
|
|
||||||
// receipt root
|
|
||||||
EmptyListRoot,
|
|
||||||
// bloom
|
|
||||||
ZeroHash512,
|
|
||||||
// Difficulty
|
|
||||||
//ethutil.BigPow(2, 22),
|
|
||||||
big.NewInt(131072),
|
|
||||||
// Number
|
|
||||||
ethutil.Big0,
|
|
||||||
// Block upper gas bound
|
|
||||||
big.NewInt(1000000),
|
|
||||||
// Block gas used
|
|
||||||
ethutil.Big0,
|
|
||||||
// Time
|
|
||||||
ethutil.Big0,
|
|
||||||
// Extra
|
|
||||||
nil,
|
|
||||||
// Nonce
|
|
||||||
crypto.Sha3(big.NewInt(42).Bytes()),
|
|
||||||
}
|
|
||||||
|
|
||||||
var Genesis = []interface{}{GenesisHeader, []interface{}{}, []interface{}{}}
|
genesis.SetUncles([]*types.Header{})
|
||||||
|
genesis.SetTransactions(types.Transactions{})
|
||||||
|
genesis.SetReceipts(types.Receipts{})
|
||||||
|
|
||||||
|
statedb := state.New(genesis.Trie())
|
||||||
|
for _, addr := range []string{
|
||||||
|
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
|
||||||
|
"e4157b34ea9615cfbde6b4fda419828124b70c78",
|
||||||
|
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
|
||||||
|
"6c386a4b26f73c802f34673f7248bb118f97424a",
|
||||||
|
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
||||||
|
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
|
||||||
|
"e6716f9544a56c530d868e4bfbacb172315bdead",
|
||||||
|
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
|
||||||
|
} {
|
||||||
|
codedAddr := ethutil.Hex2Bytes(addr)
|
||||||
|
account := statedb.GetAccount(codedAddr)
|
||||||
|
account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200)
|
||||||
|
statedb.UpdateStateObject(account)
|
||||||
|
}
|
||||||
|
statedb.Sync()
|
||||||
|
genesis.Header().Root = statedb.Root()
|
||||||
|
|
||||||
|
return genesis
|
||||||
|
}
|
||||||
|
@ -9,41 +9,233 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlockInfo struct {
|
type Header struct {
|
||||||
Number uint64
|
// Hash to the previous block
|
||||||
Hash []byte
|
ParentHash ethutil.Bytes
|
||||||
Parent []byte
|
// Uncles of this block
|
||||||
TD *big.Int
|
UncleHash []byte
|
||||||
|
// The coin base address
|
||||||
|
Coinbase []byte
|
||||||
|
// Block Trie state
|
||||||
|
Root []byte
|
||||||
|
// Tx sha
|
||||||
|
TxHash []byte
|
||||||
|
// Receipt sha
|
||||||
|
ReceiptHash []byte
|
||||||
|
// Bloom
|
||||||
|
Bloom []byte
|
||||||
|
// Difficulty for the current block
|
||||||
|
Difficulty *big.Int
|
||||||
|
// The block number
|
||||||
|
Number *big.Int
|
||||||
|
// Gas limit
|
||||||
|
GasLimit *big.Int
|
||||||
|
// Gas used
|
||||||
|
GasUsed *big.Int
|
||||||
|
// Creation time
|
||||||
|
Time uint64
|
||||||
|
// Extra data
|
||||||
|
Extra string
|
||||||
|
// Block Nonce for verification
|
||||||
|
Nonce ethutil.Bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bi *BlockInfo) RlpDecode(data []byte) {
|
func (self *Header) rlpData(withNonce bool) []interface{} {
|
||||||
decoder := ethutil.NewValueFromBytes(data)
|
fields := []interface{}{self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra}
|
||||||
|
if withNonce {
|
||||||
bi.Number = decoder.Get(0).Uint()
|
fields = append(fields, self.Nonce)
|
||||||
bi.Hash = decoder.Get(1).Bytes()
|
|
||||||
bi.Parent = decoder.Get(2).Bytes()
|
|
||||||
bi.TD = decoder.Get(3).BigInt()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bi *BlockInfo) RlpEncode() []byte {
|
return fields
|
||||||
return ethutil.Encode([]interface{}{bi.Number, bi.Hash, bi.Parent, bi.TD})
|
}
|
||||||
|
|
||||||
|
func (self *Header) RlpData() interface{} {
|
||||||
|
return self.rlpData(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Header) Hash() []byte {
|
||||||
|
return crypto.Sha3(ethutil.Encode(self.rlpData(true)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Header) HashNoNonce() []byte {
|
||||||
|
return crypto.Sha3(ethutil.Encode(self.rlpData(false)))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Block struct {
|
||||||
|
header *Header
|
||||||
|
uncles []*Header
|
||||||
|
transactions Transactions
|
||||||
|
Td *big.Int
|
||||||
|
|
||||||
|
receipts Receipts
|
||||||
|
Reward *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBlock(parentHash []byte, coinbase []byte, root []byte, difficulty *big.Int, nonce []byte, extra string) *Block {
|
||||||
|
header := &Header{
|
||||||
|
Root: root,
|
||||||
|
ParentHash: parentHash,
|
||||||
|
Coinbase: coinbase,
|
||||||
|
Difficulty: difficulty,
|
||||||
|
Nonce: nonce,
|
||||||
|
Time: uint64(time.Now().Unix()),
|
||||||
|
Extra: extra,
|
||||||
|
GasUsed: new(big.Int),
|
||||||
|
GasLimit: new(big.Int),
|
||||||
|
}
|
||||||
|
|
||||||
|
block := &Block{header: header, Reward: new(big.Int)}
|
||||||
|
|
||||||
|
return block
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBlockWithHeader(header *Header) *Block {
|
||||||
|
return &Block{header: header}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) DecodeRLP(s *rlp.Stream) error {
|
||||||
|
if _, err := s.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var header Header
|
||||||
|
if err := s.Decode(&header); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var transactions []*Transaction
|
||||||
|
if err := s.Decode(&transactions); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var uncleHeaders []*Header
|
||||||
|
if err := s.Decode(&uncleHeaders); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tdBytes []byte
|
||||||
|
if err := s.Decode(&tdBytes); err != nil {
|
||||||
|
// If this block comes from the network that's fine. If loaded from disk it should be there
|
||||||
|
// Blocks don't store their Td when propagated over the network
|
||||||
|
} else {
|
||||||
|
self.Td = ethutil.BigD(tdBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.header = &header
|
||||||
|
self.uncles = uncleHeaders
|
||||||
|
self.transactions = transactions
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) Header() *Header {
|
||||||
|
return self.header
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) Uncles() []*Header {
|
||||||
|
return self.uncles
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) SetUncles(uncleHeaders []*Header) {
|
||||||
|
self.uncles = uncleHeaders
|
||||||
|
self.header.UncleHash = crypto.Sha3(ethutil.Encode(uncleHeaders))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) Transactions() Transactions {
|
||||||
|
return self.transactions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) Transaction(hash []byte) *Transaction {
|
||||||
|
for _, transaction := range self.transactions {
|
||||||
|
if bytes.Equal(hash, transaction.Hash()) {
|
||||||
|
return transaction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) SetTransactions(transactions Transactions) {
|
||||||
|
self.transactions = transactions
|
||||||
|
self.header.TxHash = DeriveSha(transactions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) Receipts() Receipts {
|
||||||
|
return self.receipts
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) SetReceipts(receipts Receipts) {
|
||||||
|
self.receipts = receipts
|
||||||
|
self.header.ReceiptHash = DeriveSha(receipts)
|
||||||
|
self.header.Bloom = CreateBloom(receipts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) RlpData() interface{} {
|
||||||
|
return []interface{}{self.header, self.transactions, self.uncles}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) RlpDataForStorage() interface{} {
|
||||||
|
return []interface{}{self.header, self.transactions, self.uncles, self.Td /* TODO receipts */}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header accessors (add as you need them)
|
||||||
|
func (self *Block) Number() *big.Int { return self.header.Number }
|
||||||
|
func (self *Block) NumberU64() uint64 { return self.header.Number.Uint64() }
|
||||||
|
func (self *Block) ParentHash() []byte { return self.header.ParentHash }
|
||||||
|
func (self *Block) Bloom() []byte { return self.header.Bloom }
|
||||||
|
func (self *Block) Coinbase() []byte { return self.header.Coinbase }
|
||||||
|
func (self *Block) Time() int64 { return int64(self.header.Time) }
|
||||||
|
func (self *Block) GasLimit() *big.Int { return self.header.GasLimit }
|
||||||
|
func (self *Block) GasUsed() *big.Int { return self.header.GasUsed }
|
||||||
|
func (self *Block) Hash() []byte { return self.header.Hash() }
|
||||||
|
func (self *Block) Trie() *trie.Trie { return trie.New(ethutil.Config.Db, self.header.Root) }
|
||||||
|
func (self *Block) State() *state.StateDB { return state.New(self.Trie()) }
|
||||||
|
func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) }
|
||||||
|
|
||||||
|
// Implement block.Pow
|
||||||
|
func (self *Block) Difficulty() *big.Int { return self.header.Difficulty }
|
||||||
|
func (self *Block) N() []byte { return self.header.Nonce }
|
||||||
|
func (self *Block) HashNoNonce() []byte {
|
||||||
|
return crypto.Sha3(ethutil.Encode(self.header.rlpData(false)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Block) String() string {
|
||||||
|
return fmt.Sprintf(`BLOCK(%x): Size: %v {
|
||||||
|
%v
|
||||||
|
%v
|
||||||
|
%v
|
||||||
|
}
|
||||||
|
`, self.header.Hash(), self.Size(), self.header, self.uncles, self.transactions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Header) String() string {
|
||||||
|
return fmt.Sprintf(`ParentHash: %x
|
||||||
|
UncleHash: %x
|
||||||
|
Coinbase: %x
|
||||||
|
Root: %x
|
||||||
|
TxSha %x
|
||||||
|
ReceiptSha: %x
|
||||||
|
Bloom: %x
|
||||||
|
Difficulty: %v
|
||||||
|
Number: %v
|
||||||
|
GasLimit: %v
|
||||||
|
GasUsed: %v
|
||||||
|
Time: %v
|
||||||
|
Extra: %v
|
||||||
|
Nonce: %x
|
||||||
|
`, self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra, self.Nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Blocks []*Block
|
type Blocks []*Block
|
||||||
|
|
||||||
func (self Blocks) AsSet() ethutil.UniqueSet {
|
|
||||||
set := make(ethutil.UniqueSet)
|
|
||||||
for _, block := range self {
|
|
||||||
set.Insert(block.Hash())
|
|
||||||
}
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
type BlockBy func(b1, b2 *Block) bool
|
type BlockBy func(b1, b2 *Block) bool
|
||||||
|
|
||||||
func (self BlockBy) Sort(blocks Blocks) {
|
func (self BlockBy) Sort(blocks Blocks) {
|
||||||
@ -65,352 +257,4 @@ func (self blockSorter) Swap(i, j int) {
|
|||||||
}
|
}
|
||||||
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
|
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
|
||||||
|
|
||||||
func Number(b1, b2 *Block) bool { return b1.Number.Cmp(b2.Number) < 0 }
|
func Number(b1, b2 *Block) bool { return b1.Header().Number.Cmp(b2.Header().Number) < 0 }
|
||||||
|
|
||||||
type Block struct {
|
|
||||||
// Hash to the previous block
|
|
||||||
PrevHash ethutil.Bytes
|
|
||||||
// Uncles of this block
|
|
||||||
Uncles Blocks
|
|
||||||
UncleSha []byte
|
|
||||||
// The coin base address
|
|
||||||
Coinbase []byte
|
|
||||||
// Block Trie state
|
|
||||||
//state *ethutil.Trie
|
|
||||||
state *state.StateDB
|
|
||||||
// Difficulty for the current block
|
|
||||||
Difficulty *big.Int
|
|
||||||
// Creation time
|
|
||||||
Time int64
|
|
||||||
// The block number
|
|
||||||
Number *big.Int
|
|
||||||
// Gas limit
|
|
||||||
GasLimit *big.Int
|
|
||||||
// Gas used
|
|
||||||
GasUsed *big.Int
|
|
||||||
// Extra data
|
|
||||||
Extra string
|
|
||||||
// Block Nonce for verification
|
|
||||||
Nonce ethutil.Bytes
|
|
||||||
// List of transactions and/or contracts
|
|
||||||
transactions Transactions
|
|
||||||
receipts Receipts
|
|
||||||
TxSha, ReceiptSha []byte
|
|
||||||
LogsBloom []byte
|
|
||||||
|
|
||||||
Reward *big.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBlockFromBytes(raw []byte) *Block {
|
|
||||||
block := &Block{}
|
|
||||||
block.RlpDecode(raw)
|
|
||||||
|
|
||||||
return block
|
|
||||||
}
|
|
||||||
|
|
||||||
// New block takes a raw encoded string
|
|
||||||
func NewBlockFromRlpValue(rlpValue *ethutil.Value) *Block {
|
|
||||||
block := &Block{}
|
|
||||||
block.RlpValueDecode(rlpValue)
|
|
||||||
|
|
||||||
return block
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateBlock(root interface{},
|
|
||||||
prevHash []byte,
|
|
||||||
base []byte,
|
|
||||||
Difficulty *big.Int,
|
|
||||||
Nonce []byte,
|
|
||||||
extra string) *Block {
|
|
||||||
|
|
||||||
block := &Block{
|
|
||||||
PrevHash: prevHash,
|
|
||||||
Coinbase: base,
|
|
||||||
Difficulty: Difficulty,
|
|
||||||
Nonce: Nonce,
|
|
||||||
Time: time.Now().Unix(),
|
|
||||||
Extra: extra,
|
|
||||||
UncleSha: nil,
|
|
||||||
GasUsed: new(big.Int),
|
|
||||||
GasLimit: new(big.Int),
|
|
||||||
}
|
|
||||||
block.SetUncles([]*Block{})
|
|
||||||
|
|
||||||
block.state = state.New(trie.New(ethutil.Config.Db, root))
|
|
||||||
|
|
||||||
return block
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a hash of the block
|
|
||||||
func (block *Block) Hash() ethutil.Bytes {
|
|
||||||
return crypto.Sha3(ethutil.NewValue(block.header()).Encode())
|
|
||||||
//return crypto.Sha3(block.Value().Encode())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) HashNoNonce() []byte {
|
|
||||||
return crypto.Sha3(ethutil.Encode(block.miningHeader()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) State() *state.StateDB {
|
|
||||||
return block.state
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) Transactions() Transactions {
|
|
||||||
return block.transactions
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) CalcGasLimit(parent *Block) *big.Int {
|
|
||||||
if block.Number.Cmp(big.NewInt(0)) == 0 {
|
|
||||||
return ethutil.BigPow(10, 6)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024
|
|
||||||
|
|
||||||
previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit)
|
|
||||||
current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed), big.NewRat(6, 5))
|
|
||||||
curInt := new(big.Int).Div(current.Num(), current.Denom())
|
|
||||||
|
|
||||||
result := new(big.Int).Add(previous, curInt)
|
|
||||||
result.Div(result, big.NewInt(1024))
|
|
||||||
|
|
||||||
min := big.NewInt(125000)
|
|
||||||
|
|
||||||
return ethutil.BigMax(min, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) BlockInfo() BlockInfo {
|
|
||||||
bi := BlockInfo{}
|
|
||||||
data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...))
|
|
||||||
bi.RlpDecode(data)
|
|
||||||
|
|
||||||
return bi
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) GetTransaction(hash []byte) *Transaction {
|
|
||||||
for _, tx := range self.transactions {
|
|
||||||
if bytes.Compare(tx.Hash(), hash) == 0 {
|
|
||||||
return tx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync the block's state and contract respectively
|
|
||||||
func (block *Block) Sync() {
|
|
||||||
block.state.Sync()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) Undo() {
|
|
||||||
// Sync the block state itself
|
|
||||||
block.state.Reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
/////// Block Encoding
|
|
||||||
func (block *Block) rlpReceipts() interface{} {
|
|
||||||
// Marshal the transactions of this block
|
|
||||||
encR := make([]interface{}, len(block.receipts))
|
|
||||||
for i, r := range block.receipts {
|
|
||||||
// Cast it to a string (safe)
|
|
||||||
encR[i] = r.RlpData()
|
|
||||||
}
|
|
||||||
|
|
||||||
return encR
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) rlpUncles() interface{} {
|
|
||||||
// Marshal the transactions of this block
|
|
||||||
uncles := make([]interface{}, len(block.Uncles))
|
|
||||||
for i, uncle := range block.Uncles {
|
|
||||||
// Cast it to a string (safe)
|
|
||||||
uncles[i] = uncle.header()
|
|
||||||
}
|
|
||||||
|
|
||||||
return uncles
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) SetUncles(uncles []*Block) {
|
|
||||||
block.Uncles = uncles
|
|
||||||
block.UncleSha = crypto.Sha3(ethutil.Encode(block.rlpUncles()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) SetReceipts(receipts Receipts) {
|
|
||||||
self.receipts = receipts
|
|
||||||
self.ReceiptSha = DeriveSha(receipts)
|
|
||||||
self.LogsBloom = CreateBloom(receipts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) SetTransactions(txs Transactions) {
|
|
||||||
self.transactions = txs
|
|
||||||
self.TxSha = DeriveSha(txs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) Value() *ethutil.Value {
|
|
||||||
return ethutil.NewValue([]interface{}{block.header(), block.transactions, block.rlpUncles()})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) RlpEncode() []byte {
|
|
||||||
// Encode a slice interface which contains the header and the list of
|
|
||||||
// transactions.
|
|
||||||
return block.Value().Encode()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) RlpDecode(data []byte) {
|
|
||||||
rlpValue := ethutil.NewValueFromBytes(data)
|
|
||||||
block.RlpValueDecode(rlpValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
|
|
||||||
block.setHeader(decoder.Get(0))
|
|
||||||
|
|
||||||
// Tx list might be empty if this is an uncle. Uncles only have their
|
|
||||||
// header set.
|
|
||||||
if decoder.Get(1).IsNil() == false { // Yes explicitness
|
|
||||||
//receipts := decoder.Get(1)
|
|
||||||
//block.receipts = make([]*Receipt, receipts.Len())
|
|
||||||
txs := decoder.Get(1)
|
|
||||||
block.transactions = make(Transactions, txs.Len())
|
|
||||||
for i := 0; i < txs.Len(); i++ {
|
|
||||||
block.transactions[i] = NewTransactionFromValue(txs.Get(i))
|
|
||||||
//receipt := NewRecieptFromValue(receipts.Get(i))
|
|
||||||
//block.transactions[i] = receipt.Tx
|
|
||||||
//block.receipts[i] = receipt
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if decoder.Get(2).IsNil() == false { // Yes explicitness
|
|
||||||
uncles := decoder.Get(2)
|
|
||||||
block.Uncles = make([]*Block, uncles.Len())
|
|
||||||
for i := 0; i < uncles.Len(); i++ {
|
|
||||||
block.Uncles[i] = NewUncleBlockFromValue(uncles.Get(i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) setHeader(header *ethutil.Value) {
|
|
||||||
self.PrevHash = header.Get(0).Bytes()
|
|
||||||
self.UncleSha = header.Get(1).Bytes()
|
|
||||||
self.Coinbase = header.Get(2).Bytes()
|
|
||||||
self.state = state.New(trie.New(ethutil.Config.Db, header.Get(3).Val))
|
|
||||||
self.TxSha = header.Get(4).Bytes()
|
|
||||||
self.ReceiptSha = header.Get(5).Bytes()
|
|
||||||
self.LogsBloom = header.Get(6).Bytes()
|
|
||||||
self.Difficulty = header.Get(7).BigInt()
|
|
||||||
self.Number = header.Get(8).BigInt()
|
|
||||||
self.GasLimit = header.Get(9).BigInt()
|
|
||||||
self.GasUsed = header.Get(10).BigInt()
|
|
||||||
self.Time = int64(header.Get(11).BigInt().Uint64())
|
|
||||||
self.Extra = header.Get(12).Str()
|
|
||||||
self.Nonce = header.Get(13).Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUncleBlockFromValue(header *ethutil.Value) *Block {
|
|
||||||
block := &Block{}
|
|
||||||
block.setHeader(header)
|
|
||||||
|
|
||||||
return block
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) Trie() *trie.Trie {
|
|
||||||
return block.state.Trie
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) Root() interface{} {
|
|
||||||
return block.state.Root()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) Diff() *big.Int {
|
|
||||||
return block.Difficulty
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) Receipts() []*Receipt {
|
|
||||||
return self.receipts
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) miningHeader() []interface{} {
|
|
||||||
return []interface{}{
|
|
||||||
// Sha of the previous block
|
|
||||||
block.PrevHash,
|
|
||||||
// Sha of uncles
|
|
||||||
block.UncleSha,
|
|
||||||
// Coinbase address
|
|
||||||
block.Coinbase,
|
|
||||||
// root state
|
|
||||||
block.Root(),
|
|
||||||
// tx root
|
|
||||||
block.TxSha,
|
|
||||||
// Sha of tx
|
|
||||||
block.ReceiptSha,
|
|
||||||
// Bloom
|
|
||||||
block.LogsBloom,
|
|
||||||
// Current block Difficulty
|
|
||||||
block.Difficulty,
|
|
||||||
// The block number
|
|
||||||
block.Number,
|
|
||||||
// Block upper gas bound
|
|
||||||
block.GasLimit,
|
|
||||||
// Block gas used
|
|
||||||
block.GasUsed,
|
|
||||||
// Time the block was found?
|
|
||||||
block.Time,
|
|
||||||
// Extra data
|
|
||||||
block.Extra,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) header() []interface{} {
|
|
||||||
return append(block.miningHeader(), block.Nonce)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) String() string {
|
|
||||||
return fmt.Sprintf(`
|
|
||||||
BLOCK(%x): Size: %v
|
|
||||||
PrevHash: %x
|
|
||||||
UncleSha: %x
|
|
||||||
Coinbase: %x
|
|
||||||
Root: %x
|
|
||||||
TxSha %x
|
|
||||||
ReceiptSha: %x
|
|
||||||
Bloom: %x
|
|
||||||
Difficulty: %v
|
|
||||||
Number: %v
|
|
||||||
MaxLimit: %v
|
|
||||||
GasUsed: %v
|
|
||||||
Time: %v
|
|
||||||
Extra: %v
|
|
||||||
Nonce: %x
|
|
||||||
NumTx: %v
|
|
||||||
`,
|
|
||||||
block.Hash(),
|
|
||||||
block.Size(),
|
|
||||||
block.PrevHash,
|
|
||||||
block.UncleSha,
|
|
||||||
block.Coinbase,
|
|
||||||
block.Root(),
|
|
||||||
block.TxSha,
|
|
||||||
block.ReceiptSha,
|
|
||||||
block.LogsBloom,
|
|
||||||
block.Difficulty,
|
|
||||||
block.Number,
|
|
||||||
block.GasLimit,
|
|
||||||
block.GasUsed,
|
|
||||||
block.Time,
|
|
||||||
block.Extra,
|
|
||||||
block.Nonce,
|
|
||||||
len(block.transactions),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) Size() ethutil.StorageSize {
|
|
||||||
return ethutil.StorageSize(len(self.RlpEncode()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implement RlpEncodable
|
|
||||||
func (self *Block) RlpData() interface{} {
|
|
||||||
return []interface{}{self.header(), self.transactions, self.rlpUncles()}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implement pow.Block
|
|
||||||
func (self *Block) N() []byte { return self.Nonce }
|
|
||||||
|
23
core/types/block_test.go
Normal file
23
core/types/block_test.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
|
||||||
|
ethutil.Config.Db, _ = ethdb.NewMemDatabase()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewBlock(t *testing.T) {
|
||||||
|
block := GenesisBlock()
|
||||||
|
data := ethutil.Encode(block)
|
||||||
|
|
||||||
|
var genesis Block
|
||||||
|
err := rlp.Decode(bytes.NewReader(data), &genesis)
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/obscuren/secp256k1-go"
|
"github.com/obscuren/secp256k1-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,22 +16,22 @@ func IsContractAddr(addr []byte) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Transaction struct {
|
type Transaction struct {
|
||||||
nonce uint64
|
AccountNonce uint64
|
||||||
recipient []byte
|
Recipient []byte
|
||||||
value *big.Int
|
Amount *big.Int
|
||||||
gas *big.Int
|
GasAmount *big.Int
|
||||||
gasPrice *big.Int
|
Price *big.Int
|
||||||
data []byte
|
Payload []byte
|
||||||
v byte
|
V uint64
|
||||||
r, s []byte
|
R, S []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
|
func NewContractCreationTx(Amount, gasAmount, price *big.Int, data []byte) *Transaction {
|
||||||
return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script}
|
return NewTransactionMessage(nil, Amount, gasAmount, price, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
|
func NewTransactionMessage(to []byte, Amount, gasAmount, price *big.Int, data []byte) *Transaction {
|
||||||
return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data}
|
return &Transaction{Recipient: to, Amount: Amount, Price: price, GasAmount: gasAmount, Payload: data}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransactionFromBytes(data []byte) *Transaction {
|
func NewTransactionFromBytes(data []byte) *Transaction {
|
||||||
@ -39,7 +41,7 @@ func NewTransactionFromBytes(data []byte) *Transaction {
|
|||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransactionFromValue(val *ethutil.Value) *Transaction {
|
func NewTransactionFromAmount(val *ethutil.Value) *Transaction {
|
||||||
tx := &Transaction{}
|
tx := &Transaction{}
|
||||||
tx.RlpValueDecode(val)
|
tx.RlpValueDecode(val)
|
||||||
|
|
||||||
@ -47,33 +49,33 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) Hash() []byte {
|
func (tx *Transaction) Hash() []byte {
|
||||||
data := []interface{}{tx.nonce, tx.gasPrice, tx.gas, tx.recipient, tx.value, tx.data}
|
data := []interface{}{tx.AccountNonce, tx.Price, tx.GasAmount, tx.Recipient, tx.Amount, tx.Payload}
|
||||||
|
|
||||||
return crypto.Sha3(ethutil.NewValue(data).Encode())
|
return crypto.Sha3(ethutil.Encode(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) Data() []byte {
|
func (self *Transaction) Data() []byte {
|
||||||
return self.data
|
return self.Payload
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) Gas() *big.Int {
|
func (self *Transaction) Gas() *big.Int {
|
||||||
return self.gas
|
return self.GasAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) GasPrice() *big.Int {
|
func (self *Transaction) GasPrice() *big.Int {
|
||||||
return self.gasPrice
|
return self.Price
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) Value() *big.Int {
|
func (self *Transaction) Value() *big.Int {
|
||||||
return self.value
|
return self.Amount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) Nonce() uint64 {
|
func (self *Transaction) Nonce() uint64 {
|
||||||
return self.nonce
|
return self.AccountNonce
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) SetNonce(nonce uint64) {
|
func (self *Transaction) SetNonce(AccountNonce uint64) {
|
||||||
self.nonce = nonce
|
self.AccountNonce = AccountNonce
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) From() []byte {
|
func (self *Transaction) From() []byte {
|
||||||
@ -81,13 +83,13 @@ func (self *Transaction) From() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) To() []byte {
|
func (self *Transaction) To() []byte {
|
||||||
return self.recipient
|
return self.Recipient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
|
func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
|
||||||
v = tx.v
|
v = byte(tx.V)
|
||||||
r = ethutil.LeftPadBytes(tx.r, 32)
|
r = ethutil.LeftPadBytes(tx.R, 32)
|
||||||
s = ethutil.LeftPadBytes(tx.s, 32)
|
s = ethutil.LeftPadBytes(tx.S, 32)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -130,42 +132,37 @@ func (tx *Transaction) Sign(privk []byte) error {
|
|||||||
|
|
||||||
sig := tx.Signature(privk)
|
sig := tx.Signature(privk)
|
||||||
|
|
||||||
tx.r = sig[:32]
|
tx.R = sig[:32]
|
||||||
tx.s = sig[32:64]
|
tx.S = sig[32:64]
|
||||||
tx.v = sig[64] + 27
|
tx.V = uint64(sig[64] + 27)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) RlpData() interface{} {
|
func (tx *Transaction) RlpData() interface{} {
|
||||||
data := []interface{}{tx.nonce, tx.gasPrice, tx.gas, tx.recipient, tx.value, tx.data}
|
data := []interface{}{tx.AccountNonce, tx.Price, tx.GasAmount, tx.Recipient, tx.Amount, tx.Payload}
|
||||||
|
|
||||||
return append(data, tx.v, new(big.Int).SetBytes(tx.r).Bytes(), new(big.Int).SetBytes(tx.s).Bytes())
|
return append(data, tx.V, new(big.Int).SetBytes(tx.R).Bytes(), new(big.Int).SetBytes(tx.S).Bytes())
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Transaction) RlpValue() *ethutil.Value {
|
|
||||||
return ethutil.NewValue(tx.RlpData())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) RlpEncode() []byte {
|
func (tx *Transaction) RlpEncode() []byte {
|
||||||
return tx.RlpValue().Encode()
|
return ethutil.Encode(tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) RlpDecode(data []byte) {
|
func (tx *Transaction) RlpDecode(data []byte) {
|
||||||
tx.RlpValueDecode(ethutil.NewValueFromBytes(data))
|
rlp.Decode(bytes.NewReader(data), tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
|
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
|
||||||
tx.nonce = decoder.Get(0).Uint()
|
tx.AccountNonce = decoder.Get(0).Uint()
|
||||||
tx.gasPrice = decoder.Get(1).BigInt()
|
tx.Price = decoder.Get(1).BigInt()
|
||||||
tx.gas = decoder.Get(2).BigInt()
|
tx.GasAmount = decoder.Get(2).BigInt()
|
||||||
tx.recipient = decoder.Get(3).Bytes()
|
tx.Recipient = decoder.Get(3).Bytes()
|
||||||
tx.value = decoder.Get(4).BigInt()
|
tx.Amount = decoder.Get(4).BigInt()
|
||||||
tx.data = decoder.Get(5).Bytes()
|
tx.Payload = decoder.Get(5).Bytes()
|
||||||
tx.v = byte(decoder.Get(6).Uint())
|
tx.V = decoder.Get(6).Uint()
|
||||||
|
tx.R = decoder.Get(7).Bytes()
|
||||||
tx.r = decoder.Get(7).Bytes()
|
tx.S = decoder.Get(8).Bytes()
|
||||||
tx.s = decoder.Get(8).Bytes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) String() string {
|
func (tx *Transaction) String() string {
|
||||||
@ -174,10 +171,10 @@ func (tx *Transaction) String() string {
|
|||||||
Contract: %v
|
Contract: %v
|
||||||
From: %x
|
From: %x
|
||||||
To: %x
|
To: %x
|
||||||
Nonce: %v
|
AccountNonce: %v
|
||||||
GasPrice: %v
|
GasAmountPrice: %v
|
||||||
Gas: %v
|
GasAmount: %v
|
||||||
Value: %v
|
Amount: %v
|
||||||
Data: 0x%x
|
Data: 0x%x
|
||||||
V: 0x%x
|
V: 0x%x
|
||||||
R: 0x%x
|
R: 0x%x
|
||||||
@ -185,17 +182,17 @@ func (tx *Transaction) String() string {
|
|||||||
Hex: %x
|
Hex: %x
|
||||||
`,
|
`,
|
||||||
tx.Hash(),
|
tx.Hash(),
|
||||||
len(tx.recipient) == 0,
|
len(tx.Recipient) == 0,
|
||||||
tx.From(),
|
tx.From(),
|
||||||
tx.recipient,
|
tx.Recipient,
|
||||||
tx.nonce,
|
tx.AccountNonce,
|
||||||
tx.gasPrice,
|
tx.Price,
|
||||||
tx.gas,
|
tx.GasAmount,
|
||||||
tx.value,
|
tx.Amount,
|
||||||
tx.data,
|
tx.Payload,
|
||||||
tx.v,
|
tx.V,
|
||||||
tx.r,
|
tx.R,
|
||||||
tx.s,
|
tx.S,
|
||||||
ethutil.Encode(tx),
|
ethutil.Encode(tx),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -220,5 +217,5 @@ func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) }
|
|||||||
type TxByNonce struct{ Transactions }
|
type TxByNonce struct{ Transactions }
|
||||||
|
|
||||||
func (s TxByNonce) Less(i, j int) bool {
|
func (s TxByNonce) Less(i, j int) bool {
|
||||||
return s.Transactions[i].nonce < s.Transactions[j].nonce
|
return s.Transactions[i].AccountNonce < s.Transactions[j].AccountNonce
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,15 @@ func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Origin() []byte { return self.msg.From() }
|
func (self *VMEnv) Origin() []byte { return self.msg.From() }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
|
||||||
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
|
func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
|
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time }
|
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
||||||
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
||||||
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
|
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
||||||
func (self *VMEnv) AddLog(log state.Log) {
|
func (self *VMEnv) AddLog(log state.Log) {
|
||||||
|
@ -235,7 +235,7 @@ func (self *Ethereum) blockBroadcastLoop() {
|
|||||||
// automatically stops if unsubscribe
|
// automatically stops if unsubscribe
|
||||||
for obj := range self.txSub.Chan() {
|
for obj := range self.txSub.Chan() {
|
||||||
event := obj.(core.NewMinedBlockEvent)
|
event := obj.(core.NewMinedBlockEvent)
|
||||||
self.server.Broadcast("eth", NewBlockMsg, event.Block.Value().Val)
|
self.server.Broadcast("eth", NewBlockMsg, event.Block.RlpData())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ func (self *ethProtocol) handle() error {
|
|||||||
}
|
}
|
||||||
block := self.chainManager.GetBlock(hash)
|
block := self.chainManager.GetBlock(hash)
|
||||||
if block != nil {
|
if block != nil {
|
||||||
blocks = append(blocks, block.Value().Raw())
|
blocks = append(blocks, block.RlpData())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self.rw.EncodeMsg(BlocksMsg, blocks...)
|
return self.rw.EncodeMsg(BlocksMsg, blocks...)
|
||||||
|
@ -56,7 +56,7 @@ type Miner struct {
|
|||||||
eth *eth.Ethereum
|
eth *eth.Ethereum
|
||||||
events event.Subscription
|
events event.Subscription
|
||||||
|
|
||||||
uncles types.Blocks
|
uncles []*types.Header
|
||||||
localTxs map[int]*LocalTx
|
localTxs map[int]*LocalTx
|
||||||
localTxId int
|
localTxId int
|
||||||
|
|
||||||
@ -184,9 +184,9 @@ func (self *Miner) mine() {
|
|||||||
block.SetUncles(self.uncles)
|
block.SetUncles(self.uncles)
|
||||||
}
|
}
|
||||||
|
|
||||||
parent := chainMan.GetBlock(block.PrevHash)
|
parent := chainMan.GetBlock(block.ParentHash())
|
||||||
coinbase := block.State().GetOrNewStateObject(block.Coinbase)
|
coinbase := block.State().GetOrNewStateObject(block.Coinbase())
|
||||||
coinbase.SetGasPool(block.CalcGasLimit(parent))
|
coinbase.SetGasPool(core.CalcGasLimit(parent, block))
|
||||||
|
|
||||||
transactions := self.finiliseTxs()
|
transactions := self.finiliseTxs()
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ func (self *Miner) mine() {
|
|||||||
// Find a valid nonce
|
// Find a valid nonce
|
||||||
nonce := self.pow.Search(block, self.powQuitCh)
|
nonce := self.pow.Search(block, self.powQuitCh)
|
||||||
if nonce != nil {
|
if nonce != nil {
|
||||||
block.Nonce = nonce
|
block.Header().Nonce = nonce
|
||||||
err := chainMan.InsertChain(types.Blocks{block})
|
err := chainMan.InsertChain(types.Blocks{block})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
minerlogger.Infoln(err)
|
minerlogger.Infoln(err)
|
||||||
|
@ -3,7 +3,7 @@ package pow
|
|||||||
import "math/big"
|
import "math/big"
|
||||||
|
|
||||||
type Block interface {
|
type Block interface {
|
||||||
Diff() *big.Int
|
Difficulty() *big.Int
|
||||||
HashNoNonce() []byte
|
HashNoNonce() []byte
|
||||||
N() []byte
|
N() []byte
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ func (pow *EasyPow) Turbo(on bool) {
|
|||||||
func (pow *EasyPow) Search(block pow.Block, stop <-chan struct{}) []byte {
|
func (pow *EasyPow) Search(block pow.Block, stop <-chan struct{}) []byte {
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
hash := block.HashNoNonce()
|
hash := block.HashNoNonce()
|
||||||
diff := block.Diff()
|
diff := block.Difficulty()
|
||||||
i := int64(0)
|
i := int64(0)
|
||||||
start := time.Now().UnixNano()
|
start := time.Now().UnixNano()
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
@ -89,5 +89,5 @@ func verify(hash []byte, diff *big.Int, nonce []byte) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Verify(block pow.Block) bool {
|
func Verify(block pow.Block) bool {
|
||||||
return verify(block.HashNoNonce(), block.Diff(), block.N())
|
return verify(block.HashNoNonce(), block.Difficulty(), block.N())
|
||||||
}
|
}
|
||||||
|
@ -42,21 +42,21 @@ func NewJSBlock(block *types.Block) *JSBlock {
|
|||||||
}
|
}
|
||||||
txlist := ethutil.NewList(ptxs)
|
txlist := ethutil.NewList(ptxs)
|
||||||
|
|
||||||
puncles := make([]*JSBlock, len(block.Uncles))
|
puncles := make([]*JSBlock, len(block.Uncles()))
|
||||||
for i, uncle := range block.Uncles {
|
for i, uncle := range block.Uncles() {
|
||||||
puncles[i] = NewJSBlock(uncle)
|
puncles[i] = NewJSBlock(types.NewBlockWithHeader(uncle))
|
||||||
}
|
}
|
||||||
ulist := ethutil.NewList(puncles)
|
ulist := ethutil.NewList(puncles)
|
||||||
|
|
||||||
return &JSBlock{
|
return &JSBlock{
|
||||||
ref: block, Size: block.Size().String(),
|
ref: block, Size: block.Size().String(),
|
||||||
Number: int(block.Number.Uint64()), GasUsed: block.GasUsed.String(),
|
Number: int(block.NumberU64()), GasUsed: block.GasUsed().String(),
|
||||||
GasLimit: block.GasLimit.String(), Hash: ethutil.Bytes2Hex(block.Hash()),
|
GasLimit: block.GasLimit().String(), Hash: ethutil.Bytes2Hex(block.Hash()),
|
||||||
Transactions: txlist, Uncles: ulist,
|
Transactions: txlist, Uncles: ulist,
|
||||||
Time: block.Time,
|
Time: block.Time(),
|
||||||
Coinbase: ethutil.Bytes2Hex(block.Coinbase),
|
Coinbase: ethutil.Bytes2Hex(block.Coinbase()),
|
||||||
PrevHash: ethutil.Bytes2Hex(block.PrevHash),
|
PrevHash: ethutil.Bytes2Hex(block.ParentHash()),
|
||||||
Bloom: ethutil.Bytes2Hex(block.LogsBloom),
|
Bloom: ethutil.Bytes2Hex(block.Bloom()),
|
||||||
Raw: block.String(),
|
Raw: block.String(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ func (self *JSBlock) ToString() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *JSBlock) GetTransaction(hash string) *JSTransaction {
|
func (self *JSBlock) GetTransaction(hash string) *JSTransaction {
|
||||||
tx := self.ref.GetTransaction(ethutil.Hex2Bytes(hash))
|
tx := self.ref.Transaction(ethutil.Hex2Bytes(hash))
|
||||||
if tx == nil {
|
if tx == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, to []byte, value, gas, price *et
|
|||||||
// Do some pre processing for our "pre" events and hooks
|
// Do some pre processing for our "pre" events and hooks
|
||||||
block := self.chainManager.NewBlock(key.Address())
|
block := self.chainManager.NewBlock(key.Address())
|
||||||
coinbase := state.GetStateObject(key.Address())
|
coinbase := state.GetStateObject(key.Address())
|
||||||
coinbase.SetGasPool(block.GasLimit)
|
coinbase.SetGasPool(block.GasLimit())
|
||||||
self.blockManager.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true)
|
self.blockManager.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true)
|
||||||
|
|
||||||
err := self.obj.TxPool().Add(tx)
|
err := self.obj.TxPool().Add(tx)
|
||||||
|
@ -28,15 +28,15 @@ func NewEnv(state *state.StateDB, block *types.Block, value *big.Int, sender []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Origin() []byte { return self.sender }
|
func (self *VMEnv) Origin() []byte { return self.sender }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
|
||||||
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
|
func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
|
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time }
|
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
||||||
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
||||||
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.value }
|
func (self *VMEnv) Value() *big.Int { return self.value }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
||||||
func (self *VMEnv) AddLog(log state.Log) {
|
func (self *VMEnv) AddLog(log state.Log) {
|
||||||
|
Loading…
Reference in New Issue
Block a user