Commit 4cd79d8d authored by obscuren's avatar obscuren

Refactored block & Transaction

* Includes new rlp decoder
parent 4b52cd51
......@@ -86,12 +86,6 @@ func (self *JSRepl) Stop() {
}
func (self *JSRepl) parseInput(code string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("[native] error", r)
}
}()
value, err := self.re.Run(code)
if err != nil {
fmt.Println(err)
......
......@@ -325,7 +325,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
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)
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) BlockNumber() *big.Int { return self.block.Number }
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
func (self *VMEnv) Time() int64 { return self.block.Time }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
func (self *VMEnv) Time() int64 { return self.block.Time() }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
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) 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) SetDepth(i int) { self.depth = i }
func (self *VMEnv) AddLog(log state.Log) {
......
......@@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/state"
"gopkg.in/fatih/set.v0"
)
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) {
coinbase := statedb.GetOrNewStateObject(block.Coinbase)
coinbase.SetGasPool(block.CalcGasLimit(parent))
coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase)
coinbase.SetGasPool(CalcGasLimit(parent, block))
// Process the transactions on to current block
receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false)
......@@ -156,7 +157,7 @@ done:
}
block.Reward = cumulativeSum
block.GasUsed = totalUsedGas
block.Header().GasUsed = totalUsedGas
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()
defer sm.mutex.Unlock()
if sm.bc.HasBlock(block.Hash()) {
return nil, nil, &KnownBlockError{block.Number, block.Hash()}
header := block.Header()
if sm.bc.HasBlock(header.Hash()) {
return nil, nil, &KnownBlockError{header.Number, header.Hash()}
}
if !sm.bc.HasBlock(block.PrevHash) {
return nil, nil, ParentError(block.PrevHash)
if !sm.bc.HasBlock(header.ParentHash) {
return nil, nil, ParentError(header.ParentHash)
}
parent := sm.bc.GetBlock(block.PrevHash)
parent := sm.bc.GetBlock(header.ParentHash)
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) {
sm.lastAttemptedBlock = block
state := parent.State().Copy()
state := state.New(parent.Trie().Copy())
// Defer the Undo on the Trie. If the block processing happened
// 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
}
header := block.Header()
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)
return
}
txSha := types.DeriveSha(block.Transactions())
if bytes.Compare(txSha, block.TxSha) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
if bytes.Compare(txSha, header.TxHash) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
return
}
receiptSha := types.DeriveSha(receipts)
if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
//chainlogger.Debugf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
fmt.Printf("%x\n", ethutil.Encode(receipts))
err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
err = fmt.Errorf("validating receipt root. received=%x got=%x", header.ReceiptHash, receiptSha)
return
}
......@@ -225,8 +227,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
state.Update(ethutil.Big0)
if !block.State().Cmp(state) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root())
if !bytes.Equal(header.Root, state.Root()) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
return
}
......@@ -238,7 +240,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
messages := state.Manifest().Messages
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())
......@@ -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) {
uncleDiff := new(big.Int)
for _, uncle := range block.Uncles {
for _, uncle := range block.Uncles() {
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 := new(big.Int)
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
// 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)
func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
expd := CalcDifficulty(block, parent)
if expd.Cmp(block.Difficulty) < 0 {
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
if expd.Cmp(block.Header().Difficulty) < 0 {
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 {
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
......@@ -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
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
......@@ -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 {
reward := new(big.Int).Set(BlockReward)
knownUncles := ethutil.Set(parent.Uncles)
nonces := ethutil.NewSet(block.Nonce)
for _, uncle := range block.Uncles {
knownUncles := set.New()
for _, uncle := range parent.Uncles() {
knownUncles.Add(uncle.Hash())
}
nonces := ethutil.NewSet(block.Header().Nonce)
for _, uncle := range block.Uncles() {
if nonces.Include(uncle.Nonce) {
// Error not unique
return UncleError("Uncle not unique")
}
uncleParent := sm.bc.GetBlock(uncle.PrevHash)
uncleParent := sm.bc.GetBlock(uncle.ParentHash)
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")
}
if knownUncles.Include(uncle.Hash()) {
if knownUncles.Has(uncle.Hash()) {
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
account := statedb.GetAccount(block.Coinbase)
account := statedb.GetAccount(block.Header().Coinbase)
// Reward amount of ether to the coinbase address
account.AddAmount(reward)
statedb.Manifest().AddMessage(&state.Message{
To: block.Coinbase,
To: block.Header().Coinbase,
Input: 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),
})
......@@ -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) {
if !sm.bc.HasBlock(block.PrevHash) {
return nil, ParentError(block.PrevHash)
if !sm.bc.HasBlock(block.Header().ParentHash) {
return nil, ParentError(block.Header().ParentHash)
}
sm.lastAttemptedBlock = block
var (
parent = sm.bc.GetBlock(block.PrevHash)
state = parent.State().Copy()
parent = sm.bc.GetBlock(block.Header().ParentHash)
state = state.New(parent.Trie().Copy())
)
defer state.Reset()
......
package core
import (
"bytes"
"fmt"
"math/big"
"sync"
......@@ -9,11 +10,13 @@ import (
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/state"
)
var chainlogger = logger.NewLogger("CHAIN")
/*
func AddTestNetFunds(block *types.Block) {
for _, addr := range []string{
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
......@@ -31,20 +34,41 @@ func AddTestNetFunds(block *types.Block) {
block.State().UpdateStateObject(account)
}
}
*/
func CalcDifficulty(block, parent *types.Block) *big.Int {
diff := new(big.Int)
adjust := new(big.Int).Rsh(parent.Difficulty, 10)
if block.Time >= parent.Time+5 {
diff.Sub(parent.Difficulty, adjust)
bh, ph := block.Header(), parent.Header()
adjust := new(big.Int).Rsh(ph.Difficulty, 10)
if bh.Time >= ph.Time+5 {
diff.Sub(ph.Difficulty, adjust)
} else {
diff.Add(parent.Difficulty, adjust)
diff.Add(ph.Difficulty, adjust)
}
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 {
//eth EthManager
processor types.BlockProcessor
......@@ -90,7 +114,7 @@ func (self *ChainManager) CurrentBlock() *types.Block {
func NewChainManager(mux *event.TypeMux) *ChainManager {
bc := &ChainManager{}
bc.genesisBlock = types.NewBlockFromBytes(ethutil.Encode(Genesis))
bc.genesisBlock = GenesisBlock()
bc.eventMux = mux
bc.setLastBlock()
......@@ -112,7 +136,7 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) {
}
func (self *ChainManager) State() *state.StateDB {
return self.CurrentBlock().State()
return state.New(self.CurrentBlock().Trie())
}
func (self *ChainManager) TransState() *state.StateDB {
......@@ -122,13 +146,11 @@ func (self *ChainManager) TransState() *state.StateDB {
func (bc *ChainManager) setLastBlock() {
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
if len(data) != 0 {
// Prep genesis
AddTestNetFunds(bc.genesisBlock)
block := types.NewBlockFromBytes(data)
bc.currentBlock = block
var block types.Block
rlp.Decode(bytes.NewReader(data), &block)
bc.currentBlock = &block
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)
bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
......@@ -144,27 +166,28 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
bc.mu.RLock()
defer bc.mu.RUnlock()
var root interface{}
hash := ZeroHash256
var root []byte
parentHash := ZeroHash256
if bc.CurrentBlock != nil {
root = bc.currentBlock.Root()
hash = bc.lastBlockHash
root = bc.currentBlock.Header().Root
parentHash = bc.lastBlockHash
}
block := types.CreateBlock(
root,
hash,
block := types.NewBlock(
parentHash,
coinbase,
root,
ethutil.BigPow(2, 32),
nil,
"")
parent := bc.currentBlock
if parent != nil {
block.Difficulty = CalcDifficulty(block, parent)
block.Number = new(big.Int).Add(bc.currentBlock.Number, ethutil.Big1)
block.GasLimit = block.CalcGasLimit(bc.currentBlock)
header := block.Header()
header.Difficulty = CalcDifficulty(block, parent)
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()
defer bc.mu.Unlock()
AddTestNetFunds(bc.genesisBlock)
bc.genesisBlock.Trie().Sync()
// Prepare the genesis block
bc.write(bc.genesisBlock)
bc.insert(bc.genesisBlock)
......@@ -193,18 +213,20 @@ func (self *ChainManager) Export() []byte {
self.mu.RLock()
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)
for block := self.currentBlock; block != nil; block = self.GetBlock(block.PrevHash) {
blocks[block.Number.Int64()] = block
blocks := make([]*types.Block, int(self.currentBlock.NumberU64())+1)
for block := self.currentBlock; block != nil; block = self.GetBlock(block.Header().ParentHash) {
blocks[block.NumberU64()] = block
}
//fmt.Println(blocks)
return nil
return ethutil.Encode(blocks)
}
func (bc *ChainManager) insert(block *types.Block) {
encodedBlock := block.RlpEncode()
encodedBlock := ethutil.Encode(block)
ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
bc.currentBlock = block
bc.lastBlockHash = block.Hash()
......@@ -213,7 +235,7 @@ func (bc *ChainManager) insert(block *types.Block) {
func (bc *ChainManager) write(block *types.Block) {
bc.writeBlockInfo(block)
encodedBlock := block.RlpEncode()
encodedBlock := ethutil.Encode(block)
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++ {
chain = append(chain, block.Hash())
if block.Number.Cmp(ethutil.Big0) <= 0 {
if block.Header().Number.Cmp(ethutil.Big0) <= 0 {
break
}
block = self.GetBlock(block.PrevHash)
block = self.GetBlock(block.Header().ParentHash)
}
return
......@@ -253,8 +275,13 @@ func (self *ChainManager) GetBlock(hash []byte) *types.Block {
if len(data) == 0 {
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 {
......@@ -262,13 +289,13 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
defer self.mu.RUnlock()
block := self.currentBlock
for ; block != nil; block = self.GetBlock(block.PrevHash) {
if block.Number.Uint64() == num {
for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
if block.Header().Number.Uint64() == num {
break
}
}
if block != nil && block.Number.Uint64() == 0 && num != 0 {
if block != nil && block.Header().Number.Uint64() == 0 && num != 0 {
return nil
}
......@@ -281,40 +308,28 @@ func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
}
func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
parent := self.GetBlock(block.PrevHash)
parent := self.GetBlock(block.Header().ParentHash)
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)
for _, uncle := range block.Uncles {
for _, uncle := range block.Uncles() {
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
}
td := new(big.Int)
td = td.Add(parentTd, uncleDiff)
td = td.Add(td, block.Difficulty)
td = td.Add(td, block.Header().Difficulty)
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
func (bc *ChainManager) writeBlockInfo(block *types.Block) {
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() {
......@@ -331,7 +346,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
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(err)
return err
......@@ -339,16 +355,16 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
self.mu.Lock()
{
self.write(block)
cblock := self.currentBlock
if td.Cmp(self.td) > 0 {
if block.Number.Cmp(new(big.Int).Add(self.currentBlock.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])
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.Header().Number, block.Hash()[:4], cblock.Header().Number, cblock.Hash()[:4])
}
self.setTotalDifficulty(td)
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
func (self *Filter) Find() []*state.Message {
earliestBlock := self.eth.ChainManager().CurrentBlock()
var earliestBlockNo uint64 = uint64(self.earliest)
if self.earliest == -1 {
earliestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
earliestBlockNo = earliestBlock.NumberU64()
}
var latestBlockNo uint64 = uint64(self.latest)
if self.latest == -1 {
latestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
latestBlockNo = earliestBlock.NumberU64()
}
var (
......@@ -93,7 +94,7 @@ func (self *Filter) Find() []*state.Message {
for i := 0; !quit && block != nil; i++ {
// Quit on latest
switch {
case block.Number.Uint64() == earliestBlockNo, block.Number.Uint64() == 0:
case block.NumberU64() == earliestBlockNo, block.NumberU64() == 0:
quit = true
case self.max <= len(messages):
break
......@@ -113,7 +114,7 @@ func (self *Filter) Find() []*state.Message {
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)))
......@@ -176,7 +177,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
var fromIncluded, toIncluded bool
if len(self.from) > 0 {
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
break
}
......@@ -187,7 +188,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
if len(self.to) > 0 {
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
break
}
......
......@@ -3,8 +3,10 @@ package core
import (
"math/big"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"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 EmptyListRoot = crypto.Sha3(ethutil.Encode(""))
var GenesisHeader = []interface{}{
// Previous hash (none)
ZeroHash256,
// Empty uncles
EmptyShaList,
// Coinbase
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()),
}
func GenesisBlock() *types.Block {
genesis := types.NewBlock(ZeroHash256, ZeroHash160, EmptyListRoot, big.NewInt(131072), crypto.Sha3(big.NewInt(42).Bytes()), "")
genesis.Header().Number = ethutil.Big0
genesis.Header().GasLimit = big.NewInt(1000000)
genesis.Header().GasUsed = ethutil.Big0
genesis.Header().Time = 0
genesis.SetUncles([]*types.Header{})
genesis.SetTransactions(types.Transactions{})
genesis.SetReceipts(types.Receipts{})
var Genesis = []interface{}{GenesisHeader, []interface{}{}, []interface{}{}}
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
}
This diff is collapsed.
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)
}
package types
import (
"bytes"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/rlp"
"github.com/obscuren/secp256k1-go"
)
......@@ -14,22 +16,22 @@ func IsContractAddr(addr []byte) bool {
}
type Transaction struct {
nonce uint64
recipient []byte
value *big.Int
gas *big.Int
gasPrice *big.Int
data []byte
v byte
r, s []byte
AccountNonce uint64
Recipient []byte
Amount *big.Int
GasAmount *big.Int
Price *big.Int
Payload []byte
V uint64
R, S []byte
}
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script}
func NewContractCreationTx(Amount, gasAmount, price *big.Int, data []byte) *Transaction {
return NewTransactionMessage(nil, Amount, gasAmount, price, data)
}
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data}
func NewTransactionMessage(to []byte, Amount, gasAmount, price *big.Int, data []byte) *Transaction {
return &Transaction{Recipient: to, Amount: Amount, Price: price, GasAmount: gasAmount, Payload: data}
}
func NewTransactionFromBytes(data []byte) *Transaction {
......@@ -39,7 +41,7 @@ func NewTransactionFromBytes(data []byte) *Transaction {
return tx
}
func NewTransactionFromValue(val *ethutil.Value) *Transaction {
func NewTransactionFromAmount(val *ethutil.Value) *Transaction {
tx := &Transaction{}
tx.RlpValueDecode(val)
......@@ -47,33 +49,33 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
}
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 {
return self.data
return self.Payload
}
func (self *Transaction) Gas() *big.Int {
return self.gas
return self.GasAmount
}
func (self *Transaction) GasPrice() *big.Int {
return self.gasPrice
return self.Price
}
func (self *Transaction) Value() *big.Int {
return self.value
return self.Amount
}
func (self *Transaction) Nonce() uint64 {
return self.nonce
return self.AccountNonce
}
func (self *Transaction) SetNonce(nonce uint64) {
self.nonce = nonce
func (self *Transaction) SetNonce(AccountNonce uint64) {
self.AccountNonce = AccountNonce
}
func (self *Transaction) From() []byte {
......@@ -81,13 +83,13 @@ func (self *Transaction) From() []byte {
}
func (self *Transaction) To() []byte {
return self.recipient
return self.Recipient
}
func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
v = tx.v
r = ethutil.LeftPadBytes(tx.r, 32)
s = ethutil.LeftPadBytes(tx.s, 32)
v = byte(tx.V)
r = ethutil.LeftPadBytes(tx.R, 32)
s = ethutil.LeftPadBytes(tx.S, 32)
return
}
......@@ -130,42 +132,37 @@ func (tx *Transaction) Sign(privk []byte) error {
sig := tx.Signature(privk)
tx.r = sig[:32]
tx.s = sig[32:64]
tx.v = sig[64] + 27
tx.R = sig[:32]
tx.S = sig[32:64]
tx.V = uint64(sig[64] + 27)
return nil
}
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())
}
func (tx *Transaction) RlpValue() *ethutil.Value {
return ethutil.NewValue(tx.RlpData())
return append(data, tx.V, new(big.Int).SetBytes(tx.R).Bytes(), new(big.Int).SetBytes(tx.S).Bytes())
}
func (tx *Transaction) RlpEncode() []byte {
return tx.RlpValue().Encode()
return ethutil.Encode(tx)
}
func (tx *Transaction) RlpDecode(data []byte) {
tx.RlpValueDecode(ethutil.NewValueFromBytes(data))
rlp.Decode(bytes.NewReader(data), tx)
}
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx.nonce = decoder.Get(0).Uint()
tx.gasPrice = decoder.Get(1).BigInt()
tx.gas = decoder.Get(2).BigInt()
tx.recipient = decoder.Get(3).Bytes()
tx.value = decoder.Get(4).BigInt()
tx.data = decoder.Get(5).Bytes()
tx.v = byte(decoder.Get(6).Uint())
tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes()
tx.AccountNonce = decoder.Get(0).Uint()
tx.Price = decoder.Get(1).BigInt()
tx.GasAmount = decoder.Get(2).BigInt()
tx.Recipient = decoder.Get(3).Bytes()
tx.Amount = decoder.Get(4).BigInt()
tx.Payload = decoder.Get(5).Bytes()
tx.V = decoder.Get(6).Uint()
tx.R = decoder.Get(7).Bytes()
tx.S = decoder.Get(8).Bytes()
}
func (tx *Transaction) String() string {
......@@ -174,10 +171,10 @@ func (tx *Transaction) String() string {
Contract: %v
From: %x
To: %x
Nonce: %v
GasPrice: %v
Gas: %v
Value: %v
AccountNonce: %v
GasAmountPrice: %v
GasAmount: %v
Amount: %v
Data: 0x%x
V: 0x%x
R: 0x%x
......@@ -185,17 +182,17 @@ func (tx *Transaction) String() string {
Hex: %x
`,
tx.Hash(),
len(tx.recipient) == 0,
len(tx.Recipient) == 0,
tx.From(),
tx.recipient,
tx.nonce,
tx.gasPrice,
tx.gas,
tx.value,
tx.data,
tx.v,
tx.r,
tx.s,
tx.Recipient,
tx.AccountNonce,
tx.Price,
tx.GasAmount,
tx.Amount,
tx.Payload,
tx.V,
tx.R,
tx.S,
ethutil.Encode(tx),
)
}
......@@ -220,5 +217,5 @@ func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) }
type TxByNonce struct{ Transactions }
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) BlockNumber() *big.Int { return self.block.Number }
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
func (self *VMEnv) Time() int64 { return self.block.Time }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
func (self *VMEnv) Time() int64 { return self.block.Time() }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
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) 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) SetDepth(i int) { self.depth = i }
func (self *VMEnv) AddLog(log state.Log) {
......
......@@ -235,7 +235,7 @@ func (self *Ethereum) blockBroadcastLoop() {
// automatically stops if unsubscribe
for obj := range self.txSub.Chan() {
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)
if block != nil {
blocks = append(blocks, block.Value().Raw())
blocks = append(blocks, block.RlpData())
}
}
return self.rw.EncodeMsg(BlocksMsg, blocks...)
......
......@@ -56,7 +56,7 @@ type Miner struct {
eth *eth.Ethereum
events event.Subscription
uncles types.Blocks
uncles []*types.Header
localTxs map[int]*LocalTx
localTxId int
......@@ -184,9 +184,9 @@ func (self *Miner) mine() {
block.SetUncles(self.uncles)
}
parent := chainMan.GetBlock(block.PrevHash)
coinbase := block.State().GetOrNewStateObject(block.Coinbase)
coinbase.SetGasPool(block.CalcGasLimit(parent))
parent := chainMan.GetBlock(block.ParentHash())
coinbase := block.State().GetOrNewStateObject(block.Coinbase())
coinbase.SetGasPool(core.CalcGasLimit(parent, block))
transactions := self.finiliseTxs()
......@@ -211,7 +211,7 @@ func (self *Miner) mine() {
// Find a valid nonce
nonce := self.pow.Search(block, self.powQuitCh)
if nonce != nil {
block.Nonce = nonce
block.Header().Nonce = nonce
err := chainMan.InsertChain(types.Blocks{block})
if err != nil {
minerlogger.Infoln(err)
......
......@@ -3,7 +3,7 @@ package pow
import "math/big"
type Block interface {
Diff() *big.Int
Difficulty() *big.Int
HashNoNonce() []byte
N() []byte
}
......@@ -35,7 +35,7 @@ func (pow *EasyPow) Turbo(on bool) {
func (pow *EasyPow) Search(block pow.Block, stop <-chan struct{}) []byte {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
hash := block.HashNoNonce()
diff := block.Diff()
diff := block.Difficulty()
i := int64(0)
start := time.Now().UnixNano()
t := time.Now()
......@@ -89,5 +89,5 @@ func verify(hash []byte, diff *big.Int, nonce []byte) 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)
puncles := make([]*JSBlock, len(block.Uncles))
for i, uncle := range block.Uncles {
puncles[i] = NewJSBlock(uncle)
puncles := make([]*JSBlock, len(block.Uncles()))
for i, uncle := range block.Uncles() {
puncles[i] = NewJSBlock(types.NewBlockWithHeader(uncle))
}
ulist := ethutil.NewList(puncles)
return &JSBlock{
ref: block, Size: block.Size().String(),
Number: int(block.Number.Uint64()), GasUsed: block.GasUsed.String(),
GasLimit: block.GasLimit.String(), Hash: ethutil.Bytes2Hex(block.Hash()),
Number: int(block.NumberU64()), GasUsed: block.GasUsed().String(),
GasLimit: block.GasLimit().String(), Hash: ethutil.Bytes2Hex(block.Hash()),
Transactions: txlist, Uncles: ulist,
Time: block.Time,
Coinbase: ethutil.Bytes2Hex(block.Coinbase),
PrevHash: ethutil.Bytes2Hex(block.PrevHash),
Bloom: ethutil.Bytes2Hex(block.LogsBloom),
Time: block.Time(),
Coinbase: ethutil.Bytes2Hex(block.Coinbase()),
PrevHash: ethutil.Bytes2Hex(block.ParentHash()),
Bloom: ethutil.Bytes2Hex(block.Bloom()),
Raw: block.String(),
}
}
......@@ -70,7 +70,7 @@ func (self *JSBlock) ToString() string {
}
func (self *JSBlock) GetTransaction(hash string) *JSTransaction {
tx := self.ref.GetTransaction(ethutil.Hex2Bytes(hash))
tx := self.ref.Transaction(ethutil.Hex2Bytes(hash))
if tx == 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
block := self.chainManager.NewBlock(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)
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) BlockNumber() *big.Int { return self.block.Number }
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
func (self *VMEnv) Time() int64 { return self.block.Time }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
func (self *VMEnv) Time() int64 { return self.block.Time() }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
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) 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) SetDepth(i int) { self.depth = i }
func (self *VMEnv) AddLog(log state.Log) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment