|
|
@@ -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
|
|
|
+}
|
|
|
+*/
|