diff options
Diffstat (limited to 'chain')
-rw-r--r-- | chain/block.go | 10 | ||||
-rw-r--r-- | chain/block_manager.go | 137 | ||||
-rw-r--r-- | chain/bloom9.go | 23 | ||||
-rw-r--r-- | chain/chain_manager.go | 106 | ||||
-rw-r--r-- | chain/dagger.go | 3 | ||||
-rw-r--r-- | chain/error.go | 12 | ||||
-rw-r--r-- | chain/filter.go | 4 | ||||
-rw-r--r-- | chain/receipt.go | 60 | ||||
-rw-r--r-- | chain/state_transition.go | 36 | ||||
-rw-r--r-- | chain/transaction.go | 49 | ||||
-rw-r--r-- | chain/vm_env.go | 2 |
11 files changed, 277 insertions, 165 deletions
diff --git a/chain/block.go b/chain/block.go index 16975a2fe..a4ab560dc 100644 --- a/chain/block.go +++ b/chain/block.go @@ -238,7 +238,7 @@ func (block *Block) SetUncles(uncles []*Block) { func (self *Block) SetReceipts(receipts Receipts) { self.receipts = receipts self.ReceiptSha = DeriveSha(receipts) - self.LogsBloom = CreateBloom(self) + self.LogsBloom = CreateBloom(receipts) } func (self *Block) SetTransactions(txs Transactions) { @@ -319,8 +319,8 @@ func (block *Block) Trie() *trie.Trie { return block.state.Trie } -func (block *Block) GetRoot() interface{} { - return block.state.Trie.Root +func (block *Block) Root() interface{} { + return block.state.Root() } func (block *Block) Diff() *big.Int { @@ -340,7 +340,7 @@ func (block *Block) miningHeader() []interface{} { // Coinbase address block.Coinbase, // root state - block.state.Trie.Root, + block.Root(), // tx root block.TxSha, // Sha of tx @@ -393,7 +393,7 @@ func (block *Block) String() string { block.PrevHash, block.UncleSha, block.Coinbase, - block.state.Trie.Root, + block.Root(), block.TxSha, block.ReceiptSha, block.LogsBloom, diff --git a/chain/block_manager.go b/chain/block_manager.go index 998b1705d..efe9e0862 100644 --- a/chain/block_manager.go +++ b/chain/block_manager.go @@ -3,9 +3,9 @@ package chain import ( "bytes" "container/list" + "errors" "fmt" "math/big" - "os" "sync" "time" @@ -88,28 +88,11 @@ func NewBlockManager(ethereum EthManager) *BlockManager { } func (self *BlockManager) Start() { - statelogger.Debugln("Starting state manager") - self.events = self.eth.EventMux().Subscribe(Blocks(nil)) - go self.updateThread() + statelogger.Debugln("Starting block manager") } func (self *BlockManager) Stop() { statelogger.Debugln("Stopping state manager") - self.events.Unsubscribe() -} - -func (self *BlockManager) updateThread() { - for ev := range self.events.Chan() { - for _, block := range ev.(Blocks) { - err := self.Process(block) - if err != nil { - statelogger.Infoln(err) - statelogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4]) - statelogger.Debugln(block) - break - } - } - } } func (sm *BlockManager) CurrentState() *state.State { @@ -168,7 +151,6 @@ done: erroneous = append(erroneous, tx) err = nil continue - //return nil, nil, nil, err } } @@ -177,21 +159,8 @@ done: txGas.Sub(txGas, st.gas) cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas)) - //receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative} - receipt := &Receipt{ethutil.CopyBytes(state.Root().([]byte)), cumulative, LogsBloom(state.Logs()).Bytes(), state.Logs()} - - if i < len(block.Receipts()) { - original := block.Receipts()[i] - if !original.Cmp(receipt) { - if ethutil.Config.Diff { - os.Exit(1) - } - - err := fmt.Errorf("#%d receipt failed (r) %v ~ %x <=> (c) %v ~ %x (%x...)", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], tx.Hash()[0:4]) - - return nil, nil, nil, nil, err - } - } + receipt := &Receipt{ethutil.CopyBytes(state.Root()), cumulative, nil /*bloom*/, state.Logs()} + receipt.Bloom = CreateBloom(Receipts{receipt}) // Notify all subscribers go self.eth.EventMux().Post(TxPostEvent{tx}) @@ -204,30 +173,32 @@ done: } } - parent.GasUsed = totalUsedGas + block.GasUsed = totalUsedGas return receipts, handled, unhandled, erroneous, err } -func (sm *BlockManager) Process(block *Block) (err error) { +func (sm *BlockManager) Process(block *Block) (td *big.Int, msgs state.Messages, err error) { // Processing a blocks may never happen simultaneously sm.mutex.Lock() defer sm.mutex.Unlock() if sm.bc.HasBlock(block.Hash()) { - return nil + return nil, nil, nil } if !sm.bc.HasBlock(block.PrevHash) { - return ParentError(block.PrevHash) + return nil, nil, ParentError(block.PrevHash) } + parent := sm.bc.GetBlock(block.PrevHash) + return sm.ProcessWithParent(block, parent) +} + +func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, messages state.Messages, err error) { sm.lastAttemptedBlock = block - var ( - parent = sm.bc.GetBlock(block.PrevHash) - state = parent.State() - ) + state := parent.State().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 @@ -239,63 +210,66 @@ func (sm *BlockManager) Process(block *Block) (err error) { fmt.Printf("## %x %x ##\n", block.Hash(), block.Number) } - txSha := DeriveSha(block.transactions) - if bytes.Compare(txSha, block.TxSha) != 0 { - return fmt.Errorf("Error validating transaction sha. Received %x, got %x", block.TxSha, txSha) - } - receipts, err := sm.ApplyDiff(state, parent, block) if err != nil { - return err + return + } + + txSha := DeriveSha(block.transactions) + if bytes.Compare(txSha, block.TxSha) != 0 { + err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha) + return } receiptSha := DeriveSha(receipts) if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { - return fmt.Errorf("Error validating receipt sha. Received %x, got %x", block.ReceiptSha, receiptSha) + err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) + return } - // TODO validate bloom - // Block validation - if err = sm.ValidateBlock(block); err != nil { - statelogger.Errorln("Error validating block:", err) - return err + if err = sm.ValidateBlock(block, parent); err != nil { + statelogger.Errorln("validating block:", err) + return } if err = sm.AccumelateRewards(state, block, parent); err != nil { - statelogger.Errorln("Error accumulating reward", err) - return err + statelogger.Errorln("accumulating reward", err) + return + } + + block.receipts = receipts // although this isn't necessary it be in the future + rbloom := CreateBloom(receipts) + if bytes.Compare(rbloom, block.LogsBloom) != 0 { + err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) + return } state.Update() if !block.State().Cmp(state) { - err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().Trie.Root, state.Trie.Root) + err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root()) return } // Calculate the new total difficulty and sync back to the db - if sm.CalculateTD(block) { + if td, ok := sm.CalculateTD(block); ok { // Sync the current block's state to the database and cancelling out the deferred Undo state.Sync() - // Add the block to the chain - sm.bc.Add(block) + messages := state.Manifest().Messages + state.Manifest().Reset() - // TODO at this point we should also insert LOGS in to a database + chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4]) sm.transState = state.Copy() - statelogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4]) - - state.Manifest().Reset() - sm.eth.TxPool().RemoveSet(block.Transactions()) + + return td, messages, nil } else { - statelogger.Errorln("total diff failed") + return nil, nil, errors.New("total diff failed") } - - return nil } func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *Block) (receipts Receipts, err error) { @@ -311,7 +285,7 @@ func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *Block) (rec return receipts, nil } -func (sm *BlockManager) CalculateTD(block *Block) bool { +func (sm *BlockManager) CalculateTD(block *Block) (*big.Int, bool) { uncleDiff := new(big.Int) for _, uncle := range block.Uncles { uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty) @@ -325,30 +299,19 @@ func (sm *BlockManager) CalculateTD(block *Block) bool { // The new TD will only be accepted if the new difficulty is // is greater than the previous. if td.Cmp(sm.bc.TD) > 0 { - // Set the new total difficulty back to the block chain - sm.bc.SetTotalDifficulty(td) + return td, true - return true + // Set the new total difficulty back to the block chain + //sm.bc.SetTotalDifficulty(td) } - return false + return nil, false } // Validates the current block. Returns an error if the block was invalid, // an uncle or anything that isn't on the current block chain. // Validation validates easy over difficult (dagger takes longer time = difficult) -func (sm *BlockManager) ValidateBlock(block *Block) error { - // Check each uncle's previous hash. In order for it to be valid - // is if it has the same block hash as the current - parent := sm.bc.GetBlock(block.PrevHash) - /* - for _, uncle := range block.Uncles { - if bytes.Compare(uncle.PrevHash,parent.PrevHash) != 0 { - return ValidationError("Mismatch uncle's previous hash. Expected %x, got %x",parent.PrevHash, uncle.PrevHash) - } - } - */ - +func (sm *BlockManager) ValidateBlock(block, parent *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) @@ -387,7 +350,7 @@ func (sm *BlockManager) AccumelateRewards(state *state.State, block, parent *Blo uncleParent := sm.bc.GetBlock(uncle.PrevHash) if uncleParent == nil { - return UncleError("Uncle's parent unknown") + return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.PrevHash[0:4])) } if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 { diff --git a/chain/bloom9.go b/chain/bloom9.go index 2bbc9409d..c610bd101 100644 --- a/chain/bloom9.go +++ b/chain/bloom9.go @@ -8,31 +8,30 @@ import ( "github.com/ethereum/go-ethereum/state" ) -func CreateBloom(block *Block) []byte { +func CreateBloom(receipts Receipts) []byte { bin := new(big.Int) - bin.Or(bin, bloom9(crypto.Sha3(block.Coinbase))) - for _, receipt := range block.Receipts() { - bin.Or(bin, LogsBloom(receipt.logs)) + for _, receipt := range receipts { + bin.Or(bin, logsBloom(receipt.logs)) } return ethutil.LeftPadBytes(bin.Bytes(), 64) } -func LogsBloom(logs state.Logs) *big.Int { +func logsBloom(logs state.Logs) *big.Int { bin := new(big.Int) for _, log := range logs { - data := [][]byte{crypto.Sha3(log.Address)} + data := [][]byte{log.Address} for _, topic := range log.Topics { data = append(data, topic) } - if log.Data != nil { - data = append(data, log.Data) - } - for _, b := range data { - bin.Or(bin, bloom9(b)) + bin.Or(bin, ethutil.BigD(bloom9(crypto.Sha3(b)).Bytes())) } + + //if log.Data != nil { + // data = append(data, log.Data) + //} } return bin @@ -51,7 +50,7 @@ func bloom9(b []byte) *big.Int { func BloomLookup(bin, topic []byte) bool { bloom := ethutil.BigD(bin) - cmp := bloom9(topic) + cmp := bloom9(crypto.Sha3(topic)) return bloom.And(bloom, cmp).Cmp(cmp) == 0 } diff --git a/chain/chain_manager.go b/chain/chain_manager.go index 8ee7a85cc..df390a4c0 100644 --- a/chain/chain_manager.go +++ b/chain/chain_manager.go @@ -2,11 +2,13 @@ package chain import ( "bytes" + "container/list" "fmt" "math/big" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/state" ) var chainlogger = logger.NewLogger("CHAIN") @@ -22,6 +24,8 @@ type ChainManager struct { CurrentBlock *Block LastBlockHash []byte + + workingChain *BlockChain } func NewChainManager(ethereum EthManager) *ChainManager { @@ -43,7 +47,7 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *Block { hash := ZeroHash256 if bc.CurrentBlock != nil { - root = bc.CurrentBlock.state.Trie.Root + root = bc.CurrentBlock.Root() hash = bc.LastBlockHash } @@ -86,7 +90,7 @@ func (bc *ChainManager) Reset() { bc.genesisBlock.state.Trie.Sync() // Prepare the genesis block - bc.Add(bc.genesisBlock) + bc.add(bc.genesisBlock) bc.CurrentBlock = bc.genesisBlock bc.SetTotalDifficulty(ethutil.Big("0")) @@ -135,6 +139,7 @@ func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain // 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 { @@ -191,9 +196,8 @@ func (bc *ChainManager) SetTotalDifficulty(td *big.Int) { } // Add a block to the chain and record addition information -func (bc *ChainManager) Add(block *Block) { +func (bc *ChainManager) add(block *Block) { bc.writeBlockInfo(block) - // Prepare the genesis block bc.CurrentBlock = block bc.LastBlockHash = block.Hash() @@ -201,6 +205,8 @@ func (bc *ChainManager) Add(block *Block) { encodedBlock := block.RlpEncode() ethutil.Config.Db.Put(block.Hash(), encodedBlock) ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) + + //chainlogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4]) } func (self *ChainManager) CalcTotalDiff(block *Block) (*big.Int, error) { @@ -223,9 +229,18 @@ func (self *ChainManager) CalcTotalDiff(block *Block) (*big.Int, error) { return td, nil } -func (bc *ChainManager) GetBlock(hash []byte) *Block { +func (self *ChainManager) GetBlock(hash []byte) *Block { data, _ := ethutil.Config.Db.Get(hash) if len(data) == 0 { + if self.workingChain != nil { + // Check the temp chain + for e := self.workingChain.Front(); e != nil; e = e.Next() { + if bytes.Compare(e.Value.(*link).block.Hash(), hash) == 0 { + return e.Value.(*link).block + } + } + } + return nil } @@ -287,3 +302,84 @@ func (bc *ChainManager) Stop() { chainlogger.Infoln("Stopped") } } + +type link struct { + block *Block + messages state.Messages + td *big.Int +} + +type BlockChain struct { + *list.List +} + +func NewChain(blocks Blocks) *BlockChain { + chain := &BlockChain{list.New()} + + for _, block := range blocks { + chain.PushBack(&link{block, nil, nil}) + } + + return chain +} + +// This function assumes you've done your checking. No checking is done at this stage anymore +func (self *ChainManager) InsertChain(chain *BlockChain) { + for e := chain.Front(); e != nil; e = e.Next() { + link := e.Value.(*link) + + self.add(link.block) + self.SetTotalDifficulty(link.td) + self.Ethereum.EventMux().Post(NewBlockEvent{link.block}) + self.Ethereum.EventMux().Post(link.messages) + } + + b, e := chain.Front(), chain.Back() + if b != nil && e != nil { + front, back := b.Value.(*link).block, e.Value.(*link).block + chainlogger.Infof("Imported %d blocks. #%v (%x) / %#v (%x)", chain.Len(), front.Number, front.Hash()[0:4], back.Number, back.Hash()[0:4]) + } +} + +func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error) { + self.workingChain = chain + defer func() { self.workingChain = nil }() + + for e := chain.Front(); e != nil; e = e.Next() { + var ( + l = e.Value.(*link) + block = l.block + parent = self.GetBlock(block.PrevHash) + ) + + //fmt.Println("parent", parent) + //fmt.Println("current", block) + + if parent == nil { + err = fmt.Errorf("incoming chain broken on hash %x\n", block.PrevHash[0:4]) + return + } + + var messages state.Messages + td, messages, err = self.Ethereum.BlockManager().ProcessWithParent(block, parent) + if err != nil { + chainlogger.Infoln(err) + chainlogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4]) + chainlogger.Debugln(block) + + err = fmt.Errorf("incoming chain failed %v\n", err) + return + } + l.td = td + l.messages = messages + } + + if td.Cmp(self.TD) <= 0 { + err = &TDError{td, self.TD} + return + } + + self.workingChain = nil + + return +} diff --git a/chain/dagger.go b/chain/dagger.go index 3333e002d..2cf70e091 100644 --- a/chain/dagger.go +++ b/chain/dagger.go @@ -47,6 +47,7 @@ func (pow *EasyPow) Search(block *Block, stop <-chan struct{}) []byte { select { case <-stop: powlogger.Infoln("Breaking from mining") + pow.HashRate = 0 return nil default: i++ @@ -55,7 +56,7 @@ func (pow *EasyPow) Search(block *Block, stop <-chan struct{}) []byte { elapsed := time.Now().UnixNano() - start hashes := ((float64(1e9) / float64(elapsed)) * float64(i)) / 1000 pow.HashRate = int64(hashes) - powlogger.Infoln("Hashing @", int64(pow.HashRate), "khash") + powlogger.Infoln("Hashing @", pow.HashRate, "khash") t = time.Now() } diff --git a/chain/error.go b/chain/error.go index 204b8b873..540eda95a 100644 --- a/chain/error.go +++ b/chain/error.go @@ -114,3 +114,15 @@ func IsOutOfGasErr(err error) bool { return ok } + +type TDError struct { + a, b *big.Int +} + +func (self *TDError) Error() string { + return fmt.Sprintf("incoming chain has a lower or equal TD (%v <= %v)", self.a, self.b) +} +func IsTDError(e error) bool { + _, ok := e.(*TDError) + return ok +} diff --git a/chain/filter.go b/chain/filter.go index 3494e4dcc..3c0b02d4f 100644 --- a/chain/filter.go +++ b/chain/filter.go @@ -3,7 +3,9 @@ package chain import ( "bytes" "math" + "math/big" + "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" ) @@ -184,7 +186,7 @@ func (self *Filter) bloomFilter(block *Block) bool { if len(self.to) > 0 { for _, to := range self.to { - if BloomLookup(block.LogsBloom, to) { + if BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) { toIncluded = true break } diff --git a/chain/receipt.go b/chain/receipt.go new file mode 100644 index 000000000..fa53f1cdb --- /dev/null +++ b/chain/receipt.go @@ -0,0 +1,60 @@ +package chain + +import ( + "bytes" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/state" +) + +type Receipt struct { + PostState []byte + CumulativeGasUsed *big.Int + Bloom []byte + logs state.Logs +} + +func NewRecieptFromValue(val *ethutil.Value) *Receipt { + r := &Receipt{} + r.RlpValueDecode(val) + + return r +} + +func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) { + self.PostState = decoder.Get(0).Bytes() + self.CumulativeGasUsed = decoder.Get(1).BigInt() + self.Bloom = decoder.Get(2).Bytes() + + it := decoder.Get(3).NewIterator() + for it.Next() { + self.logs = append(self.logs, state.NewLogFromValue(it.Value())) + } +} + +func (self *Receipt) RlpData() interface{} { + return []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs.RlpData()} +} + +func (self *Receipt) RlpEncode() []byte { + return ethutil.Encode(self.RlpData()) +} + +func (self *Receipt) Cmp(other *Receipt) bool { + if bytes.Compare(self.PostState, other.PostState) != 0 { + return false + } + + return true +} + +func (self *Receipt) String() string { + return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs) +} + +type Receipts []*Receipt + +func (self Receipts) Len() int { return len(self) } +func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) } diff --git a/chain/state_transition.go b/chain/state_transition.go index 41bdadedb..afe044299 100644 --- a/chain/state_transition.go +++ b/chain/state_transition.go @@ -4,7 +4,6 @@ import ( "fmt" "math/big" - "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/vm" ) @@ -229,13 +228,38 @@ func (self *StateTransition) TransitionState() (err error) { } msg.Output = ret - } else { - // Add default LOG. Default = big(sender.addr) + 1 - addr := ethutil.BigD(receiver.Address()) - self.state.AddLog(state.Log{sender.Address(), [][]byte{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes()}, nil}) } } + /* + * XXX The following _should_ replace the above transaction + * execution (also for regular calls. Will replace / test next + * phase + */ + /* + // Execute transaction + if tx.CreatesContract() { + self.rec = MakeContract(tx, self.state) + } + + address := self.Receiver().Address() + evm := vm.New(NewEnv(state, self.tx, self.block), vm.DebugVmTy) + exe := NewExecution(evm, address, self.tx.Data, self.gas, self.gas.Price, self.tx.Value) + ret, err := msg.Exec(address, self.Sender()) + if err != nil { + statelogger.Debugln(err) + } else { + if tx.CreatesContract() { + self.Receiver().Code = ret + } + msg.Output = ret + } + */ + + // Add default LOG. Default = big(sender.addr) + 1 + //addr := ethutil.BigD(receiver.Address()) + //self.state.AddLog(&state.Log{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes(), [][]byte{sender.Address()}, nil}) + return } @@ -248,6 +272,8 @@ func (self *StateTransition) Eval(msg *state.Message, script []byte, context *st ) evm := vm.New(env, vm.DebugVmTy) + // TMP this will change in the refactor + callerClosure.SetExecution(vm.NewExecution(evm, nil, nil, nil, nil, self.tx.Value)) ret, _, err = callerClosure.Call(evm, self.tx.Data) return diff --git a/chain/transaction.go b/chain/transaction.go index d393f0384..d81a0ea1b 100644 --- a/chain/transaction.go +++ b/chain/transaction.go @@ -1,7 +1,6 @@ package chain import ( - "bytes" "fmt" "math/big" @@ -117,7 +116,7 @@ func (tx *Transaction) Sender() []byte { // Validate the returned key. // Return nil if public key isn't in full format - if pubkey[0] != 4 { + if len(pubkey) != 0 && pubkey[0] != 4 { return nil } @@ -201,52 +200,6 @@ func (tx *Transaction) String() string { tx.s) } -type Receipt struct { - PostState []byte - CumulativeGasUsed *big.Int - Bloom []byte - logs state.Logs -} - -func NewRecieptFromValue(val *ethutil.Value) *Receipt { - r := &Receipt{} - r.RlpValueDecode(val) - - return r -} - -func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) { - self.PostState = decoder.Get(0).Bytes() - self.CumulativeGasUsed = decoder.Get(1).BigInt() - self.Bloom = decoder.Get(2).Bytes() - - it := decoder.Get(3).NewIterator() - for it.Next() { - self.logs = append(self.logs, state.NewLogFromValue(it.Value())) - } -} - -func (self *Receipt) RlpData() interface{} { - return []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs.RlpData()} -} - -func (self *Receipt) RlpEncode() []byte { - return ethutil.Encode(self.RlpData()) -} - -func (self *Receipt) Cmp(other *Receipt) bool { - if bytes.Compare(self.PostState, other.PostState) != 0 { - return false - } - - return true -} - -type Receipts []*Receipt - -func (self Receipts) Len() int { return len(self) } -func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) } - // Transaction slice type for basic sorting type Transactions []*Transaction diff --git a/chain/vm_env.go b/chain/vm_env.go index 53092bd10..4f3dc3ca4 100644 --- a/chain/vm_env.go +++ b/chain/vm_env.go @@ -31,7 +31,7 @@ func (self *VMEnv) BlockHash() []byte { return self.block.Hash() } func (self *VMEnv) Value() *big.Int { return self.tx.Value } func (self *VMEnv) State() *state.State { return self.state } func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit } -func (self *VMEnv) AddLog(log state.Log) { +func (self *VMEnv) AddLog(log *state.Log) { self.state.AddLog(log) } func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { |