diff options
Diffstat (limited to 'ethchain/block.go')
-rw-r--r-- | ethchain/block.go | 144 |
1 files changed, 75 insertions, 69 deletions
diff --git a/ethchain/block.go b/ethchain/block.go index b98d806d8..e4a1aaf24 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -96,9 +96,10 @@ type Block struct { // Block Nonce for verification Nonce ethutil.Bytes // List of transactions and/or contracts - transactions []*Transaction - receipts []*Receipt - TxSha []byte + transactions Transactions + receipts Receipts + TxSha, ReceiptSha []byte + LogsBloom []byte } func NewBlockFromBytes(raw []byte) *Block { @@ -151,7 +152,7 @@ func (block *Block) Hash() ethutil.Bytes { func (block *Block) HashNoNonce() []byte { return ethcrypto.Sha3(ethutil.Encode([]interface{}{block.PrevHash, block.UncleSha, block.Coinbase, block.state.Trie.Root, - block.TxSha, block.Difficulty, block.Number, block.MinGasPrice, + block.ReceiptSha, block.Difficulty, block.Number, block.MinGasPrice, block.GasLimit, block.GasUsed, block.Time, block.Extra})) } @@ -191,9 +192,9 @@ func (block *Block) BlockInfo() BlockInfo { } func (self *Block) GetTransaction(hash []byte) *Transaction { - for _, receipt := range self.receipts { - if bytes.Compare(receipt.Tx.Hash(), hash) == 0 { - return receipt.Tx + for _, tx := range self.transactions { + if bytes.Compare(tx.Hash(), hash) == 0 { + return tx } } @@ -236,10 +237,7 @@ func (block *Block) rlpUncles() interface{} { func (block *Block) SetUncles(uncles []*Block) { block.Uncles = uncles - // Sha of the concatenated uncles - if len(uncles) > 0 { - block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles())) - } + block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles())) } func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) { @@ -249,32 +247,20 @@ func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) { func (block *Block) setTransactions(txs []*Transaction) { block.transactions = txs -} - -func CreateTxSha(receipts Receipts) (sha []byte) { - trie := ethtrie.New(ethutil.Config.Db, "") - for i, receipt := range receipts { - trie.Update(string(ethutil.NewValue(i).Encode()), string(ethutil.NewValue(receipt.RlpData()).Encode())) - } - switch trie.Root.(type) { - case string: - sha = []byte(trie.Root.(string)) - case []byte: - sha = trie.Root.([]byte) - default: - panic(fmt.Sprintf("invalid root type %T", trie.Root)) - } + block.LogsBloom = CreateBloom(txs) +} - return sha +func (self *Block) SetTransactionHash(transactions Transactions) { + self.TxSha = DeriveSha(transactions) } -func (self *Block) SetTxHash(receipts Receipts) { - self.TxSha = CreateTxSha(receipts) +func (self *Block) SetReceiptHash(receipts Receipts) { + self.ReceiptSha = DeriveSha(receipts) } func (block *Block) Value() *ethutil.Value { - return ethutil.NewValue([]interface{}{block.header(), block.rlpReceipts(), block.rlpUncles()}) + return ethutil.NewValue([]interface{}{block.header(), block.transactions, block.rlpUncles()}) } func (block *Block) RlpEncode() []byte { @@ -289,33 +275,20 @@ func (block *Block) RlpDecode(data []byte) { } func (block *Block) RlpValueDecode(decoder *ethutil.Value) { - header := decoder.Get(0) - - block.PrevHash = header.Get(0).Bytes() - block.UncleSha = header.Get(1).Bytes() - block.Coinbase = header.Get(2).Bytes() - 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() - //fmt.Printf("#%v : %x\n", block.Number, block.Coinbase) - block.MinGasPrice = header.Get(7).BigInt() - block.GasLimit = header.Get(8).BigInt() - block.GasUsed = header.Get(9).BigInt() - block.Time = int64(header.Get(10).BigInt().Uint64()) - block.Extra = header.Get(11).Str() - block.Nonce = header.Get(12).Bytes() + block.setHeader(decoder.Get(0)) // Tx list might be empty if this is an uncle. Uncles only have their // header set. if decoder.Get(1).IsNil() == false { // Yes explicitness - receipts := decoder.Get(1) - block.transactions = make([]*Transaction, receipts.Len()) - block.receipts = make([]*Receipt, receipts.Len()) - for i := 0; i < receipts.Len(); i++ { - receipt := NewRecieptFromValue(receipts.Get(i)) - block.transactions[i] = receipt.Tx - block.receipts[i] = receipt + //receipts := decoder.Get(1) + //block.receipts = make([]*Receipt, receipts.Len()) + it := decoder.Get(1).NewIterator() + block.transactions = make(Transactions, it.Len()) + for it.Next() { + block.transactions[it.Idx()] = NewTransactionFromValue(it.Value()) + //receipt := NewRecieptFromValue(receipts.Get(i)) + //block.transactions[i] = receipt.Tx + //block.receipts[i] = receipt } } @@ -330,22 +303,27 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) { } +func (self *Block) setHeader(header *ethutil.Value) { + self.PrevHash = header.Get(0).Bytes() + self.UncleSha = header.Get(1).Bytes() + self.Coinbase = header.Get(2).Bytes() + self.state = ethstate.New(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) + self.TxSha = header.Get(4).Bytes() + self.ReceiptSha = header.Get(5).Bytes() + self.LogsBloom = header.Get(6).Bytes() + self.Difficulty = header.Get(7).BigInt() + self.Number = header.Get(8).BigInt() + self.MinGasPrice = header.Get(9).BigInt() + self.GasLimit = header.Get(10).BigInt() + self.GasUsed = header.Get(11).BigInt() + self.Time = int64(header.Get(12).BigInt().Uint64()) + self.Extra = header.Get(13).Str() + self.Nonce = header.Get(14).Bytes() +} + func NewUncleBlockFromValue(header *ethutil.Value) *Block { block := &Block{} - - block.PrevHash = header.Get(0).Bytes() - block.UncleSha = header.Get(1).Bytes() - block.Coinbase = header.Get(2).Bytes() - 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() - block.MinGasPrice = header.Get(7).BigInt() - block.GasLimit = header.Get(8).BigInt() - block.GasUsed = header.Get(9).BigInt() - block.Time = int64(header.Get(10).BigInt().Uint64()) - block.Extra = header.Get(11).Str() - block.Nonce = header.Get(12).Bytes() + block.setHeader(header) return block } @@ -376,8 +354,12 @@ func (block *Block) header() []interface{} { block.Coinbase, // root state block.state.Trie.Root, - // Sha of tx + // tx root block.TxSha, + // Sha of tx + block.ReceiptSha, + // Bloom + block.LogsBloom, // Current block Difficulty block.Difficulty, // The block number @@ -404,7 +386,9 @@ func (block *Block) String() string { UncleSha: %x Coinbase: %x Root: %x - TxSha: %x + TxSha %x + ReceiptSha: %x + Bloom: %x Difficulty: %v Number: %v MinGas: %v @@ -422,6 +406,8 @@ func (block *Block) String() string { block.Coinbase, block.state.Trie.Root, block.TxSha, + block.ReceiptSha, + block.LogsBloom, block.Difficulty, block.Number, block.MinGasPrice, @@ -437,3 +423,23 @@ func (block *Block) String() string { func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(self.RlpEncode())) } + +/* +func DeriveReceiptHash(receipts Receipts) (sha []byte) { + trie := ethtrie.New(ethutil.Config.Db, "") + for i, receipt := range receipts { + trie.Update(string(ethutil.NewValue(i).Encode()), string(ethutil.NewValue(receipt.RlpData()).Encode())) + } + + switch trie.Root.(type) { + case string: + sha = []byte(trie.Root.(string)) + case []byte: + sha = trie.Root.([]byte) + default: + panic(fmt.Sprintf("invalid root type %T", trie.Root)) + } + + return sha +} +*/ |