Updated chain for filtering

This commit is contained in:
obscuren
2014-08-11 16:23:38 +02:00
parent 2e5d28c73f
commit a760ce05b9
14 changed files with 164 additions and 74 deletions

View File

@@ -142,19 +142,6 @@ func (block *Block) CalcGasLimit(parent *Block) *big.Int {
min := big.NewInt(125000)
return ethutil.BigMax(min, result)
/*
base := new(big.Int)
base2 := new(big.Int)
parentGL := bc.CurrentBlock.GasLimit
parentUsed := bc.CurrentBlock.GasUsed
base.Mul(parentGL, big.NewInt(1024-1))
base2.Mul(parentUsed, big.NewInt(6))
base2.Div(base2, big.NewInt(5))
base.Add(base, base2)
base.Div(base, big.NewInt(1024))
*/
}
func (block *Block) BlockInfo() BlockInfo {

View File

@@ -300,6 +300,8 @@ func (bc *BlockChain) setLastBlock() {
bc.genesisBlock.state.Trie.Sync()
// Prepare the genesis block
bc.Add(bc.genesisBlock)
fk := append([]byte("bloom"), bc.genesisBlock.Hash()...)
bc.Ethereum.Db().Put(fk, make([]byte, 255))
}
// Set the last know difficulty (might be 0x0 as initial value, Genesis)

View File

@@ -3,16 +3,19 @@ package ethchain
import (
"container/list"
"fmt"
"testing"
"github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethdb"
"github.com/ethereum/eth-go/ethreact"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire"
"testing"
)
// Implement our EthTest Manager
type TestManager struct {
stateManager *StateManager
reactor *ethutil.ReactorEngine
reactor *ethreact.ReactorEngine
txPool *TxPool
blockChain *BlockChain
@@ -47,16 +50,24 @@ func (tm *TestManager) StateManager() *StateManager {
return tm.stateManager
}
func (tm *TestManager) Reactor() *ethutil.ReactorEngine {
func (tm *TestManager) Reactor() *ethreact.ReactorEngine {
return tm.reactor
}
func (tm *TestManager) Broadcast(msgType ethwire.MsgType, data []interface{}) {
fmt.Println("Broadcast not implemented")
}
func NewTestManager() *TestManager {
func (tm *TestManager) ClientIdentity() ethwire.ClientIdentity {
return nil
}
func (tm *TestManager) KeyManager() *ethcrypto.KeyManager {
return nil
}
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "", "ETH")
func (tm *TestManager) Db() ethutil.Database { return nil }
func NewTestManager() *TestManager {
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "ETH")
db, err := ethdb.NewMemDatabase()
if err != nil {
@@ -66,7 +77,7 @@ func NewTestManager() *TestManager {
ethutil.Config.Db = db
testManager := &TestManager{}
testManager.reactor = ethutil.NewReactorEngine()
testManager.reactor = ethreact.New()
testManager.txPool = NewTxPool(testManager)
testManager.blockChain = NewBlockChain(testManager)

View File

@@ -45,6 +45,7 @@ type EthManager interface {
Peers() *list.List
KeyManager() *ethcrypto.KeyManager
ClientIdentity() ethwire.ClientIdentity
Db() ethutil.Database
}
type StateManager struct {
@@ -235,7 +236,12 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// Add the block to the chain
sm.bc.Add(block)
sm.notifyChanges(state)
// Create a bloom bin for this block
filter := sm.createBloomFilter(state)
// Persist the data
fk := append([]byte("bloom"), block.Hash()...)
sm.Ethereum.Db().Put(fk, filter.Bin())
statelogger.Infof("Added block #%d (%x)\n", block.Number, block.Hash())
if dontReact == false {
@@ -363,14 +369,74 @@ func (sm *StateManager) Stop() {
sm.bc.Stop()
}
func (sm *StateManager) notifyChanges(state *ethstate.State) {
// Manifest will handle both creating notifications and generating bloom bin data
func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
bloomf := NewBloomFilter(nil)
for addr, stateObject := range state.Manifest().ObjectChanges {
// Set the bloom filter's bin
bloomf.Set([]byte(addr))
sm.Ethereum.Reactor().Post("object:"+addr, stateObject)
}
for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges {
for addr, value := range mappedObjects {
// Set the bloom filter's bin
bloomf.Set(ethcrypto.Sha3Bin([]byte(stateObjectAddr + addr)))
sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, &ethstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value})
}
}
return bloomf
}
func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message, err error) {
if !sm.bc.HasBlock(block.PrevHash) {
return nil, ParentError(block.PrevHash)
}
sm.lastAttemptedBlock = block
var (
parent = sm.bc.GetBlock(block.PrevHash)
state = parent.State().Copy()
)
defer state.Reset()
if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
}
receipts, err := sm.ApplyDiff(state, parent, block)
if err != nil {
return nil, err
}
txSha := CreateTxSha(receipts)
if bytes.Compare(txSha, block.TxSha) != 0 {
return nil, fmt.Errorf("Error validating tx sha. Received %x, got %x", block.TxSha, txSha)
}
// Block validation
if err = sm.ValidateBlock(block); err != nil {
statelogger.Errorln("Error validating block:", err)
return nil, err
}
// I'm not sure, but I don't know if there should be thrown
// any errors at this time.
if err = sm.AccumelateRewards(state, block); err != nil {
statelogger.Errorln("Error accumulating reward", err)
return nil, err
}
if !block.State().Cmp(state) {
err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().Trie.Root, state.Trie.Root)
return nil, err
}
return state.Manifest().Messages, nil
}

View File

@@ -211,6 +211,13 @@ func (self *StateTransition) TransitionState() (err error) {
snapshot = self.state.Copy()
}
msg := self.state.Manifest().AddMessage(&ethstate.Message{
To: receiver.Address(), From: sender.Address(),
Input: self.tx.Data,
Origin: sender.Address(),
Block: self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number,
})
// Process the init code and create 'valid' contract
if IsContractAddr(self.receiver) {
// Evaluate the initialization script
@@ -226,14 +233,17 @@ func (self *StateTransition) TransitionState() (err error) {
}
receiver.Code = code
msg.Output = code
} else {
if len(receiver.Code) > 0 {
_, err = self.Eval(receiver.Code, receiver, "code")
ret, err := self.Eval(receiver.Code, receiver, "code")
if err != nil {
self.state.Set(snapshot)
return fmt.Errorf("Error during code execution %v", err)
}
msg.Output = ret
}
}

View File

@@ -1,8 +1,9 @@
package ethchain
import (
"github.com/ethereum/eth-go/ethstate"
"math/big"
"github.com/ethereum/eth-go/ethstate"
)
type VMEnv struct {
@@ -25,5 +26,6 @@ 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) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) Value() *big.Int { return self.tx.Value }
func (self *VMEnv) State() *ethstate.State { return self.state }