From 1735ec0362e84455126d8c1bd380ecae436d1167 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 15 Jul 2014 01:11:06 +0100 Subject: use ethreact.Event and ethreact.ReactorEngine --- ethchain/dagger.go | 5 +++-- ethchain/state_manager.go | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'ethchain') diff --git a/ethchain/dagger.go b/ethchain/dagger.go index 4dda21ff5..adf1c2f05 100644 --- a/ethchain/dagger.go +++ b/ethchain/dagger.go @@ -3,6 +3,7 @@ package ethchain import ( "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethlog" + "github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethutil" "github.com/obscuren/sha3" "hash" @@ -14,7 +15,7 @@ import ( var powlogger = ethlog.NewLogger("POW") type PoW interface { - Search(block *Block, reactChan chan ethutil.React) []byte + Search(block *Block, reactChan chan ethreact.Event) []byte Verify(hash []byte, diff *big.Int, nonce []byte) bool } @@ -22,7 +23,7 @@ type EasyPow struct { hash *big.Int } -func (pow *EasyPow) Search(block *Block, reactChan chan ethutil.React) []byte { +func (pow *EasyPow) Search(block *Block, reactChan chan ethreact.Event) []byte { r := rand.New(rand.NewSource(time.Now().UnixNano())) hash := block.HashNoNonce() diff := block.Difficulty diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 62fcda8a5..3eafd2d6e 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethlog" + "github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" @@ -36,7 +37,7 @@ type EthManager interface { BlockChain() *BlockChain TxPool() *TxPool Broadcast(msgType ethwire.MsgType, data []interface{}) - Reactor() *ethutil.ReactorEngine + Reactor() *ethreact.ReactorEngine PeerCount() int IsMining() bool IsListening() bool -- cgit v1.2.3 From 41bd38147c2e5968283facf641b2444c09f53d14 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 26 Jul 2014 11:24:44 +0200 Subject: Clean up and util methods --- ethchain/block.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block.go b/ethchain/block.go index 437525e35..e00bcb24f 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -3,13 +3,14 @@ package ethchain import ( "bytes" "fmt" + "math/big" + _ "strconv" + "time" + "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" - "math/big" - _ "strconv" - "time" ) type BlockInfo struct { @@ -63,12 +64,6 @@ type Block struct { TxSha []byte } -// New block takes a raw encoded string -// XXX DEPRICATED -func NewBlockFromData(raw []byte) *Block { - return NewBlockFromBytes(raw) -} - func NewBlockFromBytes(raw []byte) *Block { block := &Block{} block.RlpDecode(raw) -- cgit v1.2.3 From 1f9894c0845a5259adbfd30fe3a86631e6403b8d Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 30 Jul 2014 00:31:15 +0200 Subject: Old code removed and renamed amount to balance --- ethchain/block.go | 27 --------------- ethchain/block_chain.go | 7 ++-- ethchain/state_transition.go | 15 +++++---- ethchain/transaction_pool.go | 79 +++----------------------------------------- 4 files changed, 16 insertions(+), 112 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block.go b/ethchain/block.go index e00bcb24f..ac56f58c3 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -125,33 +125,6 @@ func (block *Block) Transactions() []*Transaction { return block.transactions } -func (block *Block) PayFee(addr []byte, fee *big.Int) bool { - contract := block.state.GetStateObject(addr) - // If we can't pay the fee return - if contract == nil || contract.Amount.Cmp(fee) < 0 /* amount < fee */ { - fmt.Println("Contract has insufficient funds", contract.Amount, fee) - - return false - } - - base := new(big.Int) - contract.Amount = base.Sub(contract.Amount, fee) - block.state.Trie.Update(string(addr), string(contract.RlpEncode())) - - data := block.state.Trie.Get(string(block.Coinbase)) - - // Get the ether (Coinbase) and add the fee (gief fee to miner) - account := ethstate.NewStateObjectFromBytes(block.Coinbase, []byte(data)) - - base = new(big.Int) - account.Amount = base.Add(account.Amount, fee) - - //block.state.Trie.Update(string(block.Coinbase), string(ether.RlpEncode())) - block.state.UpdateStateObject(account) - - return true -} - func (block *Block) CalcGasLimit(parent *Block) *big.Int { if block.Number.Cmp(big.NewInt(0)) == 0 { return ethutil.BigPow(10, 6) diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 1a2662787..250903798 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -2,11 +2,12 @@ package ethchain import ( "bytes" + "math" + "math/big" + "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" - "math" - "math/big" ) var chainlogger = ethlog.NewLogger("CHAIN") @@ -280,7 +281,7 @@ func AddTestNetFunds(block *Block) { } { codedAddr := ethutil.Hex2Bytes(addr) account := block.state.GetAccount(codedAddr) - account.Amount = ethutil.Big("1606938044258990275541962092341162602522202993782792835301376") //ethutil.BigPow(2, 200) + account.Balance = ethutil.Big("1606938044258990275541962092341162602522202993782792835301376") //ethutil.BigPow(2, 200) block.state.UpdateStateObject(account) } } diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 266328ce8..02a8e0e82 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -2,11 +2,12 @@ package ethchain import ( "fmt" + "math/big" + "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethvm" - "math/big" ) /* @@ -94,8 +95,8 @@ func (self *StateTransition) BuyGas() error { var err error sender := self.Sender() - if sender.Amount.Cmp(self.tx.GasValue()) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Amount) + if sender.Balance.Cmp(self.tx.GasValue()) < 0 { + return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance) } coinbase := self.Coinbase() @@ -178,8 +179,8 @@ func (self *StateTransition) TransitionState() (err error) { return } - if sender.Amount.Cmp(self.value) < 0 { - return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) + if sender.Balance.Cmp(self.value) < 0 { + return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance) } var snapshot *ethstate.State @@ -240,8 +241,8 @@ func (self *StateTransition) TransitionState() (err error) { } func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObject) error { - if sender.Amount.Cmp(self.value) < 0 { - return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) + if sender.Balance.Cmp(self.value) < 0 { + return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance) } // Subtract the amount from the senders account diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go index 21c6ea3de..b0d62fd91 100644 --- a/ethchain/transaction_pool.go +++ b/ethchain/transaction_pool.go @@ -4,11 +4,12 @@ import ( "bytes" "container/list" "fmt" + "math/big" + "sync" + "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethwire" - "math/big" - "sync" ) var txplogger = ethlog.NewLogger("TXP") @@ -91,78 +92,6 @@ func (pool *TxPool) addTransaction(tx *Transaction) { pool.Ethereum.Broadcast(ethwire.MsgTxTy, []interface{}{tx.RlpData()}) } -/* -// Process transaction validates the Tx and processes funds from the -// sender to the recipient. -func (pool *TxPool) ProcessTransaction(tx *Transaction, state *State, toContract bool) (gas *big.Int, err error) { - fmt.Printf("state root before update %x\n", state.Root()) - defer func() { - if r := recover(); r != nil { - txplogger.Infoln(r) - err = fmt.Errorf("%v", r) - } - }() - - gas = new(big.Int) - addGas := func(g *big.Int) { gas.Add(gas, g) } - addGas(GasTx) - - // Get the sender - sender := state.GetAccount(tx.Sender()) - - if sender.Nonce != tx.Nonce { - err = NonceError(tx.Nonce, sender.Nonce) - return - } - - sender.Nonce += 1 - defer func() { - //state.UpdateStateObject(sender) - // Notify all subscribers - pool.Ethereum.Reactor().Post("newTx:post", tx) - }() - - txTotalBytes := big.NewInt(int64(len(tx.Data))) - txTotalBytes.Div(txTotalBytes, ethutil.Big32) - addGas(new(big.Int).Mul(txTotalBytes, GasSStore)) - - rGas := new(big.Int).Set(gas) - rGas.Mul(gas, tx.GasPrice) - - // Make sure there's enough in the sender's account. Having insufficient - // funds won't invalidate this transaction but simple ignores it. - totAmount := new(big.Int).Add(tx.Value, rGas) - if sender.Amount.Cmp(totAmount) < 0 { - err = fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender()) - return - } - state.UpdateStateObject(sender) - fmt.Printf("state root after sender update %x\n", state.Root()) - - // Get the receiver - receiver := state.GetAccount(tx.Recipient) - - // Send Tx to self - if bytes.Compare(tx.Recipient, tx.Sender()) == 0 { - // Subtract the fee - sender.SubAmount(rGas) - } else { - // Subtract the amount from the senders account - sender.SubAmount(totAmount) - - // Add the amount to receivers account which should conclude this transaction - receiver.AddAmount(tx.Value) - - state.UpdateStateObject(receiver) - fmt.Printf("state root after receiver update %x\n", state.Root()) - } - - txplogger.Infof("[TXPL] Processed Tx %x\n", tx.Hash()) - - return -} -*/ - func (pool *TxPool) ValidateTransaction(tx *Transaction) error { // Get the last block so we can retrieve the sender and receiver from // the merkle trie @@ -183,7 +112,7 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error { totAmount := new(big.Int).Set(tx.Value) // Make sure there's enough in the sender's account. Having insufficient // funds won't invalidate this transaction but simple ignores it. - if sender.Amount.Cmp(totAmount) < 0 { + if sender.Balance.Cmp(totAmount) < 0 { return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender()) } -- cgit v1.2.3 From 3debeb7236d2c8474fa9049cc91dc26bf1040b3f Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 4 Aug 2014 10:38:18 +0200 Subject: ethtrie.NewTrie => ethtrie.New --- ethchain/block.go | 24 ++++-------------------- ethchain/block_chain.go | 10 +++++----- ethchain/state_transition.go | 2 +- 3 files changed, 10 insertions(+), 26 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block.go b/ethchain/block.go index ac56f58c3..e4486f8e4 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -100,7 +100,7 @@ func CreateBlock(root interface{}, } block.SetUncles([]*Block{}) - block.state = ethstate.NewState(ethtrie.NewTrie(ethutil.Config.Db, root)) + block.state = ethstate.NewState(ethtrie.New(ethutil.Config.Db, root)) return block } @@ -220,26 +220,10 @@ func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) { func (block *Block) setTransactions(txs []*Transaction) { block.transactions = txs - - /* - trie := ethtrie.NewTrie(ethutil.Config.Db, "") - for i, tx := range txs { - trie.Update(strconv.Itoa(i), string(tx.RlpEncode())) - } - - switch trie.Root.(type) { - case string: - block.TxSha = []byte(trie.Root.(string)) - case []byte: - block.TxSha = trie.Root.([]byte) - default: - panic(fmt.Sprintf("invalid root type %T", trie.Root)) - } - */ } func CreateTxSha(receipts Receipts) (sha []byte) { - trie := ethtrie.NewTrie(ethutil.Config.Db, "") + trie := ethtrie.New(ethutil.Config.Db, "") for i, receipt := range receipts { trie.Update(string(ethutil.NewValue(i).Encode()), string(ethutil.NewValue(receipt.RlpData()).Encode())) } @@ -281,7 +265,7 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) { block.PrevHash = header.Get(0).Bytes() block.UncleSha = header.Get(1).Bytes() block.Coinbase = header.Get(2).Bytes() - block.state = ethstate.NewState(ethtrie.NewTrie(ethutil.Config.Db, header.Get(3).Val)) + block.state = ethstate.NewState(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) block.TxSha = header.Get(4).Bytes() block.Difficulty = header.Get(5).BigInt() block.Number = header.Get(6).BigInt() @@ -323,7 +307,7 @@ func NewUncleBlockFromValue(header *ethutil.Value) *Block { block.PrevHash = header.Get(0).Bytes() block.UncleSha = header.Get(1).Bytes() block.Coinbase = header.Get(2).Bytes() - block.state = ethstate.NewState(ethtrie.NewTrie(ethutil.Config.Db, header.Get(3).Val)) + block.state = ethstate.NewState(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) block.TxSha = header.Get(4).Bytes() block.Difficulty = header.Get(5).BigInt() block.Number = header.Get(6).BigInt() diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 250903798..736fe52c7 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -132,7 +132,7 @@ func (bc *BlockChain) FindCanonicalChain(blocks []*Block, commonBlockHash []byte // Start with the newest block we got, all the way back to the common block we both know for _, block := range blocks { if bytes.Compare(block.Hash(), commonBlockHash) == 0 { - chainlogger.Infoln("[CHAIN] We have found the common parent block, breaking") + chainlogger.Infoln("We have found the common parent block, breaking") break } chainDifficulty.Add(chainDifficulty, bc.CalculateBlockTD(block)) @@ -145,13 +145,13 @@ func (bc *BlockChain) FindCanonicalChain(blocks []*Block, commonBlockHash []byte for i := 0; block != nil; block = bc.GetBlock(block.PrevHash) { i++ if bytes.Compare(block.Hash(), commonBlockHash) == 0 { - chainlogger.Infoln("We have found the common parent block, breaking") + chainlogger.Infoln("Found the common parent block") break } anOtherBlock := bc.GetBlock(block.PrevHash) if anOtherBlock == nil { // We do not want to count the genesis block for difficulty since that's not being sent - chainlogger.Infoln("At genesis block, breaking") + chainlogger.Infoln("Found genesis block. Stop") break } curChainDifficulty.Add(curChainDifficulty, bc.CalculateBlockTD(block)) @@ -159,11 +159,11 @@ func (bc *BlockChain) FindCanonicalChain(blocks []*Block, commonBlockHash []byte chainlogger.Infoln("Current chain difficulty:", curChainDifficulty) if chainDifficulty.Cmp(curChainDifficulty) == 1 { - chainlogger.Infof("The incoming Chain beat our asses, resetting to block: %x", commonBlockHash) + chainlogger.Infof("Resetting to block %x. Changing chain.") bc.ResetTillBlockHash(commonBlockHash) return false } else { - chainlogger.Infoln("Our chain showed the incoming chain who is boss. Ignoring.") + chainlogger.Infoln("Current chain is longest chain. Ignoring incoming chain.") return true } } diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 02a8e0e82..8f1561c00 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -278,7 +278,7 @@ func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject contract := state.NewStateObject(addr) contract.InitCode = tx.Data - contract.State = ethstate.NewState(ethtrie.NewTrie(ethutil.Config.Db, "")) + contract.State = ethstate.NewState(ethtrie.New(ethutil.Config.Db, "")) return contract } -- cgit v1.2.3 From 03ce15df4c7ef51d4373233ab5c3766282b31771 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 4 Aug 2014 10:42:40 +0200 Subject: ethstate.NewState => ethstate.New --- ethchain/block.go | 6 +++--- ethchain/state_transition.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block.go b/ethchain/block.go index e4486f8e4..321af6183 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -100,7 +100,7 @@ func CreateBlock(root interface{}, } block.SetUncles([]*Block{}) - block.state = ethstate.NewState(ethtrie.New(ethutil.Config.Db, root)) + block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, root)) return block } @@ -265,7 +265,7 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) { block.PrevHash = header.Get(0).Bytes() block.UncleSha = header.Get(1).Bytes() block.Coinbase = header.Get(2).Bytes() - block.state = ethstate.NewState(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) + block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) block.TxSha = header.Get(4).Bytes() block.Difficulty = header.Get(5).BigInt() block.Number = header.Get(6).BigInt() @@ -307,7 +307,7 @@ func NewUncleBlockFromValue(header *ethutil.Value) *Block { block.PrevHash = header.Get(0).Bytes() block.UncleSha = header.Get(1).Bytes() block.Coinbase = header.Get(2).Bytes() - block.state = ethstate.NewState(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) + block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) block.TxSha = header.Get(4).Bytes() block.Difficulty = header.Get(5).BigInt() block.Number = header.Get(6).BigInt() diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 8f1561c00..dfcbfcc04 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -278,7 +278,7 @@ func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject contract := state.NewStateObject(addr) contract.InitCode = tx.Data - contract.State = ethstate.NewState(ethtrie.New(ethutil.Config.Db, "")) + contract.State = ethstate.New(ethtrie.New(ethutil.Config.Db, "")) return contract } -- cgit v1.2.3 From da50c751480da32036f41ccbeb1f292694ca0286 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 6 Aug 2014 09:53:00 +0200 Subject: Added state dump method --- ethchain/block_chain.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 736fe52c7..3eba90fca 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -290,7 +290,6 @@ func (bc *BlockChain) setLastBlock() { data, _ := ethutil.Config.Db.Get([]byte("LastBlock")) if len(data) != 0 { block := NewBlockFromBytes(data) - //info := bc.BlockInfo(block) bc.CurrentBlock = block bc.LastBlockHash = block.Hash() bc.LastBlockNumber = block.Number.Uint64() @@ -301,9 +300,6 @@ func (bc *BlockChain) setLastBlock() { bc.genesisBlock.state.Trie.Sync() // Prepare the genesis block bc.Add(bc.genesisBlock) - - //chainlogger.Infof("root %x\n", bm.bc.genesisBlock.State().Root) - //bm.bc.genesisBlock.PrintHash() } // Set the last know difficulty (might be 0x0 as initial value, Genesis) @@ -339,6 +335,18 @@ func (bc *BlockChain) GetBlock(hash []byte) *Block { return NewBlockFromBytes(data) } +func (self *BlockChain) GetBlockByNumber(num uint64) *Block { + block := self.CurrentBlock + for ; block.Number.Uint64() != num; block = self.GetBlock(block.PrevHash) { + } + + if block.Number.Uint64() == 0 && num != 0 { + return nil + } + + return block +} + func (bc *BlockChain) BlockInfoByHash(hash []byte) BlockInfo { bi := BlockInfo{} data, _ := ethutil.Config.Db.Get(append(hash, []byte("Info")...)) -- cgit v1.2.3 From c51db4c940a5ea679aee580a673a4ccdd2421b9a Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 8 Aug 2014 14:36:59 +0100 Subject: Fixed stack issue --- ethchain/state_manager.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'ethchain') diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 226b2fe73..f06622fcb 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -4,15 +4,16 @@ import ( "bytes" "container/list" "fmt" + "math/big" + "sync" + "time" + "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" - "math/big" - "sync" - "time" ) var statelogger = ethlog.NewLogger("STATE") -- cgit v1.2.3 From 27290e12772f4a354cfdc6383222597f66cefa21 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 9 Aug 2014 18:06:16 +0100 Subject: Fixed gas limit calculation --- ethchain/block.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block.go b/ethchain/block.go index 321af6183..5b06fd58d 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -130,8 +130,10 @@ func (block *Block) CalcGasLimit(parent *Block) *big.Int { return ethutil.BigPow(10, 6) } - previous := new(big.Int).Mul(big.NewInt(1023), parent.GasLimit) - current := new(big.Rat).Mul(new(big.Rat).SetInt(block.GasUsed), big.NewRat(6, 5)) + // ((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) -- cgit v1.2.3 From 024be32f0667c17b9240dda23a90612d17278b23 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 9 Aug 2014 18:09:55 +0100 Subject: Make sure all left padded zero's aren't included --- ethchain/transaction.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ethchain') diff --git a/ethchain/transaction.go b/ethchain/transaction.go index 5686a7edb..e1b48a3d3 100644 --- a/ethchain/transaction.go +++ b/ethchain/transaction.go @@ -3,10 +3,11 @@ package ethchain import ( "bytes" "fmt" + "math/big" + "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethutil" "github.com/obscuren/secp256k1-go" - "math/big" ) var ContractAddr = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} @@ -130,7 +131,7 @@ func (tx *Transaction) RlpData() interface{} { // TODO Remove prefixing zero's - return append(data, tx.v, tx.r, tx.s) + 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 { -- cgit v1.2.3 From 2e5d28c73f1d97865def3ffe8c7ad0a4819f15f3 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 11 Aug 2014 16:23:17 +0200 Subject: Added bloom filter & block filter methods --- ethchain/bloom.go | 47 ++++++++++++++++ ethchain/bloom_test.go | 20 +++++++ ethchain/filter.go | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ ethchain/filter_test.go | 7 +++ 4 files changed, 220 insertions(+) create mode 100644 ethchain/bloom.go create mode 100644 ethchain/bloom_test.go create mode 100644 ethchain/filter.go create mode 100644 ethchain/filter_test.go (limited to 'ethchain') diff --git a/ethchain/bloom.go b/ethchain/bloom.go new file mode 100644 index 000000000..320ce73fc --- /dev/null +++ b/ethchain/bloom.go @@ -0,0 +1,47 @@ +package ethchain + +type BloomFilter struct { + bin []byte +} + +func NewBloomFilter(bin []byte) *BloomFilter { + if bin == nil { + bin = make([]byte, 255) + } + + return &BloomFilter{ + bin: bin, + } +} + +func (self *BloomFilter) Set(addr []byte) { + if len(addr) < 8 { + chainlogger.Warnf("err: bloom set to small: %x\n", addr) + + return + } + + for _, i := range addr[len(addr)-8:] { + self.bin[i] = 1 + } +} + +func (self *BloomFilter) Search(addr []byte) bool { + if len(addr) < 8 { + chainlogger.Warnf("err: bloom search to small: %x\n", addr) + + return false + } + + for _, i := range addr[len(addr)-8:] { + if self.bin[i] == 0 { + return false + } + } + + return true +} + +func (self *BloomFilter) Bin() []byte { + return self.bin +} diff --git a/ethchain/bloom_test.go b/ethchain/bloom_test.go new file mode 100644 index 000000000..ea53d539c --- /dev/null +++ b/ethchain/bloom_test.go @@ -0,0 +1,20 @@ +package ethchain + +import "testing" + +func TestBloomFilter(t *testing.T) { + bf := NewBloomFilter(nil) + + a := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} + bf.Set(a) + + b := []byte{10, 11, 12, 13, 14, 15, 16, 17, 18, 19} + + if bf.Search(a) == false { + t.Error("Expected 'a' to yield true using a bloom filter") + } + + if bf.Search(b) { + t.Error("Expected 'b' not to field trie using a bloom filter") + } +} diff --git a/ethchain/filter.go b/ethchain/filter.go new file mode 100644 index 000000000..c3b0a7f94 --- /dev/null +++ b/ethchain/filter.go @@ -0,0 +1,146 @@ +package ethchain + +import ( + "bytes" + "fmt" + + "github.com/ethereum/eth-go/ethstate" + "github.com/ethereum/eth-go/ethutil" +) + +// Filtering interface +type Filter struct { + eth EthManager + earliest []byte + latest []byte + skip int + from, to []byte + max int +} + +// Create a new filter which uses a bloom filter on blocks to figure out whether a particular block +// is interesting or not. +func NewFilter(eth EthManager) *Filter { + return &Filter{eth: eth} +} + +// Set the earliest and latest block for filtering. +// -1 = latest block (i.e., the current block) +// hash = particular hash from-to +func (self *Filter) SetEarliestBlock(earliest interface{}) { + e := ethutil.NewValue(earliest) + + // Check for -1 (latest) otherwise assume bytes + if e.Int() == -1 { + self.earliest = self.eth.BlockChain().CurrentBlock.Hash() + } else if e.Len() > 0 { + self.earliest = e.Bytes() + } else { + panic(fmt.Sprintf("earliest has to be either -1 or a valid hash: %v (%T)", e, e.Val)) + } +} + +func (self *Filter) SetLatestBlock(latest interface{}) { + l := ethutil.NewValue(latest) + + // Check for -1 (latest) otherwise assume bytes + if l.Int() == -1 { + self.latest = self.eth.BlockChain().CurrentBlock.Hash() + } else if l.Len() > 0 { + self.latest = l.Bytes() + } else { + panic(fmt.Sprintf("latest has to be either -1 or a valid hash: %v", l)) + } +} + +func (self *Filter) SetFrom(addr []byte) { + self.from = addr +} + +func (self *Filter) SetTo(addr []byte) { + self.to = addr +} + +func (self *Filter) SetMax(max int) { + self.max = max +} + +func (self *Filter) SetSkip(skip int) { + self.skip = skip +} + +// Run filters messages with the current parameters set +func (self *Filter) Find() []*ethstate.Message { + var messages []*ethstate.Message + + block := self.eth.BlockChain().GetBlock(self.latest) + + // skip N blocks (useful for pagination) + if self.skip > 0 { + for i := 0; i < i; i++ { + block = self.eth.BlockChain().GetBlock(block.PrevHash) + } + } + + // Start block filtering + quit := false + for i := 1; !quit && block != nil; i++ { + // Mark last check + if self.max == i || (len(self.earliest) > 0 && bytes.Compare(block.Hash(), self.earliest) == 0) { + quit = true + } + + // Use bloom filtering to see if this block is interesting given the + // current parameters + if self.bloomFilter(block) { + // Get the messages of the block + msgs, err := self.eth.StateManager().GetMessages(block) + if err != nil { + chainlogger.Warnln("err: filter get messages ", err) + + break + } + + // Filter the messages for interesting stuff + for _, message := range msgs { + if len(self.to) > 0 && bytes.Compare(message.To, self.to) != 0 { + continue + } + + if len(self.from) > 0 && bytes.Compare(message.From, self.from) != 0 { + continue + } + + messages = append(messages, message) + } + } + + block = self.eth.BlockChain().GetBlock(block.PrevHash) + } + + return messages +} + +func (self *Filter) bloomFilter(block *Block) bool { + fk := append([]byte("bloom"), block.Hash()...) + bin, err := self.eth.Db().Get(fk) + if err != nil { + panic(err) + } + + bloom := NewBloomFilter(bin) + + if len(self.from) > 0 { + if !bloom.Search(self.from) { + return false + } + } + + if len(self.to) > 0 { + if !bloom.Search(self.to) { + return false + } + } + + return true +} diff --git a/ethchain/filter_test.go b/ethchain/filter_test.go new file mode 100644 index 000000000..6dce51b3b --- /dev/null +++ b/ethchain/filter_test.go @@ -0,0 +1,7 @@ +package ethchain + +import "testing" + +func TestFilter(t *testing.T) { + filter := NewFilter() +} -- cgit v1.2.3 From a760ce05b948e89bc564af20599dcf95698ac0eb Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 11 Aug 2014 16:23:38 +0200 Subject: Updated chain for filtering --- ethchain/block.go | 13 -------- ethchain/block_chain.go | 2 ++ ethchain/block_chain_test.go | 23 +++++++++++---- ethchain/state_manager.go | 70 ++++++++++++++++++++++++++++++++++++++++++-- ethchain/state_transition.go | 12 +++++++- ethchain/vm_env.go | 4 ++- 6 files changed, 101 insertions(+), 23 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block.go b/ethchain/block.go index 5b06fd58d..5765abd51 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -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 { diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 3eba90fca..611735707 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -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) diff --git a/ethchain/block_chain_test.go b/ethchain/block_chain_test.go index bbc96c823..1edcf9c7b 100644 --- a/ethchain/block_chain_test.go +++ b/ethchain/block_chain_test.go @@ -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) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index f06622fcb..a60b28b3f 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -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, ðstate.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 } diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index dfcbfcc04..489ff2b6a 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -211,6 +211,13 @@ func (self *StateTransition) TransitionState() (err error) { snapshot = self.state.Copy() } + msg := self.state.Manifest().AddMessage(ðstate.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 } } diff --git a/ethchain/vm_env.go b/ethchain/vm_env.go index ddead77fd..30f9497fa 100644 --- a/ethchain/vm_env.go +++ b/ethchain/vm_env.go @@ -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 } -- cgit v1.2.3 From fa881220aedb638f9ee35337b2ca1817c2a8482f Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 13 Aug 2014 10:52:50 +0200 Subject: Updated lookup method to include CNAME's as well as A records --- ethchain/bloom.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain') diff --git a/ethchain/bloom.go b/ethchain/bloom.go index 320ce73fc..5317ca0b1 100644 --- a/ethchain/bloom.go +++ b/ethchain/bloom.go @@ -6,7 +6,7 @@ type BloomFilter struct { func NewBloomFilter(bin []byte) *BloomFilter { if bin == nil { - bin = make([]byte, 255) + bin = make([]byte, 256) } return &BloomFilter{ -- cgit v1.2.3 From 0d733aa07197c8adbbaa92a12a4ad32e86676cc7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 14 Aug 2014 17:02:21 +0200 Subject: Removed validation check from GetMessages --- ethchain/state_manager.go | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) (limited to 'ethchain') diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index a60b28b3f..d7860b2a2 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -406,37 +406,9 @@ func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message, 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 - } + sm.ApplyDiff(state, parent, block) - 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 - } + sm.AccumelateRewards(state, block) return state.Manifest().Messages, nil } -- cgit v1.2.3 From 07cfb7b64ac7932a4ff8c2480452114b84b421a6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 14 Aug 2014 17:02:39 +0200 Subject: updated filter so it accepts multiple from and to --- ethchain/filter.go | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'ethchain') diff --git a/ethchain/filter.go b/ethchain/filter.go index c3b0a7f94..65c41c42d 100644 --- a/ethchain/filter.go +++ b/ethchain/filter.go @@ -14,7 +14,7 @@ type Filter struct { earliest []byte latest []byte skip int - from, to []byte + from, to [][]byte max int } @@ -53,14 +53,22 @@ func (self *Filter) SetLatestBlock(latest interface{}) { } } -func (self *Filter) SetFrom(addr []byte) { +func (self *Filter) SetFrom(addr [][]byte) { self.from = addr } -func (self *Filter) SetTo(addr []byte) { +func (self *Filter) AddFrom(addr []byte) { + self.from = append(self.from, addr) +} + +func (self *Filter) SetTo(addr [][]byte) { self.to = addr } +func (self *Filter) AddTo(addr []byte) { + self.from = append(self.to, addr) +} + func (self *Filter) SetMax(max int) { self.max = max } @@ -101,13 +109,22 @@ func (self *Filter) Find() []*ethstate.Message { break } + includes := func(addresses [][]byte, a []byte) (found bool) { + for _, addr := range addresses { + if bytes.Compare(addr, a) == 0 { + return true + } + } + + return + } // Filter the messages for interesting stuff for _, message := range msgs { - if len(self.to) > 0 && bytes.Compare(message.To, self.to) != 0 { + if len(self.to) > 0 && !includes(self.to, message.To) { continue } - if len(self.from) > 0 && bytes.Compare(message.From, self.from) != 0 { + if len(self.from) > 0 && !includes(self.from, message.From) { continue } @@ -130,17 +147,28 @@ func (self *Filter) bloomFilter(block *Block) bool { bloom := NewBloomFilter(bin) + var fromIncluded, toIncluded bool if len(self.from) > 0 { - if !bloom.Search(self.from) { - return false + for _, from := range self.from { + if bloom.Search(from) { + fromIncluded = true + break + } } + } else { + fromIncluded = true } if len(self.to) > 0 { - if !bloom.Search(self.to) { - return false + for _, to := range self.to { + if bloom.Search(to) { + toIncluded = true + break + } } + } else { + toIncluded = true } - return true + return fromIncluded && toIncluded } -- cgit v1.2.3 From 0fcc6065692f2692072cdf0d61fe1ada547fc235 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 15 Aug 2014 00:24:37 +0200 Subject: Added new filter from map --- ethchain/filter.go | 83 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 18 deletions(-) (limited to 'ethchain') diff --git a/ethchain/filter.go b/ethchain/filter.go index 65c41c42d..4f3160b90 100644 --- a/ethchain/filter.go +++ b/ethchain/filter.go @@ -24,6 +24,46 @@ func NewFilter(eth EthManager) *Filter { return &Filter{eth: eth} } +func NewFilterFromMap(object map[string]interface{}, eth EthManager) *Filter { + filter := NewFilter(eth) + + if object["earliest"] != nil { + earliest := object["earliest"] + if e, ok := earliest.(string); ok { + filter.SetEarliestBlock(ethutil.Hex2Bytes(e)) + } else { + filter.SetEarliestBlock(earliest) + } + } + + if object["latest"] != nil { + latest := object["latest"] + if l, ok := latest.(string); ok { + filter.SetLatestBlock(ethutil.Hex2Bytes(l)) + } else { + filter.SetLatestBlock(latest) + } + } + + if object["to"] != nil { + filter.AddTo(ethutil.Hex2Bytes(object["to"].(string))) + } + + if object["from"] != nil { + filter.AddFrom(ethutil.Hex2Bytes(object["from"].(string))) + } + + if object["max"] != nil { + filter.SetMax(object["max"].(int)) + } + + if object["skip"] != nil { + filter.SetSkip(object["skip"].(int)) + } + + return filter +} + // Set the earliest and latest block for filtering. // -1 = latest block (i.e., the current block) // hash = particular hash from-to @@ -109,30 +149,37 @@ func (self *Filter) Find() []*ethstate.Message { break } - includes := func(addresses [][]byte, a []byte) (found bool) { - for _, addr := range addresses { - if bytes.Compare(addr, a) == 0 { - return true - } - } + messages = append(messages, self.FilterMessages(msgs)...) + } - return - } - // Filter the messages for interesting stuff - for _, message := range msgs { - if len(self.to) > 0 && !includes(self.to, message.To) { - continue - } + block = self.eth.BlockChain().GetBlock(block.PrevHash) + } - if len(self.from) > 0 && !includes(self.from, message.From) { - continue - } + return messages +} - messages = append(messages, message) +func (self *Filter) FilterMessages(msgs []*ethstate.Message) []*ethstate.Message { + var messages []*ethstate.Message + includes := func(addresses [][]byte, a []byte) (found bool) { + for _, addr := range addresses { + if bytes.Compare(addr, a) == 0 { + return true } } - block = self.eth.BlockChain().GetBlock(block.PrevHash) + return + } + // Filter the messages for interesting stuff + for _, message := range msgs { + if len(self.to) > 0 && !includes(self.to, message.To) { + continue + } + + if len(self.from) > 0 && !includes(self.from, message.From) { + continue + } + + messages = append(messages, message) } return messages -- cgit v1.2.3 From c7ee9844bd6f8ed2bb466f8adf21f437ecc83564 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 15 Aug 2014 00:25:16 +0200 Subject: Removed old code --- ethchain/state_manager.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'ethchain') diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index d7860b2a2..1f47a2e0b 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -380,14 +380,18 @@ func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter { 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("messages", state.Manifest().Messages) - sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, ðstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value}) + /* + 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, ðstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value}) + } } - } + */ return bloomf } -- cgit v1.2.3 From 7d95e8624a3bdca4a68b2a7ff6ed133264088cc1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 15 Aug 2014 16:19:10 +0200 Subject: Added message to closure && added change addresses --- ethchain/filter.go | 101 +++++++++++++++++++++++++++++++++++++++---- ethchain/state_manager.go | 14 ++++-- ethchain/state_transition.go | 8 ++-- 3 files changed, 107 insertions(+), 16 deletions(-) (limited to 'ethchain') diff --git a/ethchain/filter.go b/ethchain/filter.go index 4f3160b90..c4c403cf7 100644 --- a/ethchain/filter.go +++ b/ethchain/filter.go @@ -6,8 +6,13 @@ import ( "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethutil" + "gopkg.in/qml.v1" ) +type data struct { + id, address []byte +} + // Filtering interface type Filter struct { eth EthManager @@ -16,6 +21,8 @@ type Filter struct { skip int from, to [][]byte max int + + altered []data } // Create a new filter which uses a bloom filter on blocks to figure out whether a particular block @@ -61,9 +68,19 @@ func NewFilterFromMap(object map[string]interface{}, eth EthManager) *Filter { filter.SetSkip(object["skip"].(int)) } + if object["altered"] != nil { + filter.altered = makeAltered(object["altered"]) + } + + fmt.Println("ALTERED", filter.altered) + return filter } +func (self *Filter) AddAltered(id, address []byte) { + self.altered = append(self.altered, data{id, address}) +} + // Set the earliest and latest block for filtering. // -1 = latest block (i.e., the current block) // hash = particular hash from-to @@ -158,17 +175,19 @@ func (self *Filter) Find() []*ethstate.Message { return messages } +func includes(addresses [][]byte, a []byte) (found bool) { + for _, addr := range addresses { + if bytes.Compare(addr, a) == 0 { + return true + } + } + + return +} + func (self *Filter) FilterMessages(msgs []*ethstate.Message) []*ethstate.Message { var messages []*ethstate.Message - includes := func(addresses [][]byte, a []byte) (found bool) { - for _, addr := range addresses { - if bytes.Compare(addr, a) == 0 { - return true - } - } - return - } // Filter the messages for interesting stuff for _, message := range msgs { if len(self.to) > 0 && !includes(self.to, message.To) { @@ -179,6 +198,28 @@ func (self *Filter) FilterMessages(msgs []*ethstate.Message) []*ethstate.Message continue } + var match bool + if len(self.altered) == 0 { + match = true + } + + for _, item := range self.altered { + if len(item.id) > 0 && bytes.Compare(message.To, item.id) != 0 { + continue + } + + if len(item.address) > 0 && !includes(message.ChangedAddresses, item.address) { + continue + } + + match = true + break + } + + if !match { + continue + } + messages = append(messages, message) } @@ -219,3 +260,47 @@ func (self *Filter) bloomFilter(block *Block) bool { return fromIncluded && toIncluded } + +// Conversion methodn +func mapToData(m map[string]interface{}) (d data) { + if str, ok := m["id"].(string); ok { + d.id = ethutil.Hex2Bytes(str) + } + + if str, ok := m["at"].(string); ok { + d.address = ethutil.Hex2Bytes(str) + } + + return +} + +// data can come in in the following formats: +// ["aabbccdd", {id: "ccddee", at: "11223344"}], "aabbcc", {id: "ccddee", at: "1122"} +func makeAltered(v interface{}) (d []data) { + if str, ok := v.(string); ok { + d = append(d, data{ethutil.Hex2Bytes(str), nil}) + } else if obj, ok := v.(map[string]interface{}); ok { + d = append(d, mapToData(obj)) + } else if slice, ok := v.([]interface{}); ok { + for _, item := range slice { + d = append(d, makeAltered(item)...) + } + } else if qList, ok := v.(*qml.List); ok { + var s []interface{} + qList.Convert(&s) + + fmt.Println(s) + + d = makeAltered(s) + } else if qMap, ok := v.(*qml.Map); ok { + var m map[string]interface{} + qMap.Convert(&m) + fmt.Println(m) + + d = makeAltered(m) + } else { + panic(fmt.Sprintf("makeAltered err (unknown conversion): %T\n", v)) + } + + return +} diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 1f47a2e0b..08bd22d29 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -373,11 +373,17 @@ func (sm *StateManager) Stop() { 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)) + /* + for addr, stateObject := range state.Manifest().ObjectChanges { + // Set the bloom filter's bin + bloomf.Set([]byte(addr)) - sm.Ethereum.Reactor().Post("object:"+addr, stateObject) + sm.Ethereum.Reactor().Post("object:"+addr, stateObject) + } + */ + for _, msg := range state.Manifest().Messages { + bloomf.Set(msg.To) + bloomf.Set(msg.From) } sm.Ethereum.Reactor().Post("messages", state.Manifest().Messages) diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 489ff2b6a..f8452cdb3 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -225,7 +225,7 @@ func (self *StateTransition) TransitionState() (err error) { // script section for the state object. self.data = nil - code, err := self.Eval(receiver.Init(), receiver, "init") + code, err := self.Eval(msg, receiver.Init(), receiver, "init") if err != nil { self.state.Set(snapshot) @@ -236,7 +236,7 @@ func (self *StateTransition) TransitionState() (err error) { msg.Output = code } else { if len(receiver.Code) > 0 { - ret, err := self.Eval(receiver.Code, receiver, "code") + ret, err := self.Eval(msg, receiver.Code, receiver, "code") if err != nil { self.state.Set(snapshot) @@ -263,12 +263,12 @@ func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObjec return nil } -func (self *StateTransition) Eval(script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { +func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { var ( transactor = self.Sender() state = self.state env = NewEnv(state, self.tx, self.block) - callerClosure = ethvm.NewClosure(transactor, context, script, self.gas, self.gasPrice) + callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice) ) vm := ethvm.New(env) -- cgit v1.2.3 From b0ae61c6521003d7861d89944e1d426e939535bb Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 18 Aug 2014 10:17:45 +0200 Subject: Removed the "Get" part --- ethchain/state_transition.go | 1 + 1 file changed, 1 insertion(+) (limited to 'ethchain') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index f8452cdb3..9fbc160a5 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -216,6 +216,7 @@ func (self *StateTransition) TransitionState() (err error) { Input: self.tx.Data, Origin: sender.Address(), Block: self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number, + Value: self.value, }) // Process the init code and create 'valid' contract -- cgit v1.2.3 From 55a2f35a648ef70cdcc88bd751265e30831b54e5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 20 Aug 2014 13:05:26 +0200 Subject: JS Filter --- ethchain/filter.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'ethchain') diff --git a/ethchain/filter.go b/ethchain/filter.go index c4c403cf7..5ed9af977 100644 --- a/ethchain/filter.go +++ b/ethchain/filter.go @@ -72,8 +72,6 @@ func NewFilterFromMap(object map[string]interface{}, eth EthManager) *Filter { filter.altered = makeAltered(object["altered"]) } - fmt.Println("ALTERED", filter.altered) - return filter } @@ -123,7 +121,7 @@ func (self *Filter) SetTo(addr [][]byte) { } func (self *Filter) AddTo(addr []byte) { - self.from = append(self.to, addr) + self.to = append(self.to, addr) } func (self *Filter) SetMax(max int) { -- cgit v1.2.3 From eaa2e8900d1036e09b002c4e20fc6e4f9cd031bb Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 21 Aug 2014 14:47:58 +0200 Subject: PoC 6 networking code. * Added block pool for gathering blocks from the network (chunks) * Re wrote syncing --- ethchain/block_chain.go | 20 ++++++++++++++++++++ ethchain/genesis.go | 6 ++++-- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'ethchain') diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 611735707..3445bbb87 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -208,6 +208,26 @@ func (bc *BlockChain) GenesisBlock() *Block { return bc.genesisBlock } +func (self *BlockChain) GetChainHashesFromHash(hash []byte, max uint64) (chain [][]byte) { + block := self.GetBlock(hash) + if block == nil { + return + } + + // XXX Could be optimised by using a different database which only holds hashes (i.e., linked list) + for i := uint64(0); i < max; i++ { + chain = append(chain, block.Hash()) + + if block.Number.Cmp(ethutil.Big0) <= 0 { + break + } + + block = self.GetBlock(block.PrevHash) + } + + return +} + // Get chain return blocks from hash up to max in RLP format func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} { var chain []interface{} diff --git a/ethchain/genesis.go b/ethchain/genesis.go index 54a3bc766..0ce53a6ee 100644 --- a/ethchain/genesis.go +++ b/ethchain/genesis.go @@ -1,9 +1,10 @@ package ethchain import ( + "math/big" + "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethutil" - "math/big" ) /* @@ -26,7 +27,8 @@ var GenesisHeader = []interface{}{ // tx sha "", // Difficulty - ethutil.BigPow(2, 22), + //ethutil.BigPow(2, 22), + big.NewInt(4096), // Number ethutil.Big0, // Block minimum gas price -- cgit v1.2.3