| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | package ethchain | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2014-05-22 17:56:33 +02:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-07-26 11:24:44 +02:00
										 |  |  | 	"math/big" | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | 	"sort" | 
					
						
							| 
									
										
										
										
											2014-07-26 11:24:44 +02:00
										 |  |  | 	_ "strconv" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 18:30:05 +01:00
										 |  |  | 	"github.com/ethereum/eth-go/ethcrypto" | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 	"github.com/ethereum/eth-go/ethstate" | 
					
						
							| 
									
										
										
										
											2014-06-29 18:30:05 +01:00
										 |  |  | 	"github.com/ethereum/eth-go/ethtrie" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	"github.com/ethereum/eth-go/ethutil" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type BlockInfo struct { | 
					
						
							|  |  |  | 	Number uint64 | 
					
						
							|  |  |  | 	Hash   []byte | 
					
						
							|  |  |  | 	Parent []byte | 
					
						
							| 
									
										
										
										
											2014-09-24 11:39:17 +02:00
										 |  |  | 	TD     *big.Int | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (bi *BlockInfo) RlpDecode(data []byte) { | 
					
						
							|  |  |  | 	decoder := ethutil.NewValueFromBytes(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bi.Number = decoder.Get(0).Uint() | 
					
						
							|  |  |  | 	bi.Hash = decoder.Get(1).Bytes() | 
					
						
							|  |  |  | 	bi.Parent = decoder.Get(2).Bytes() | 
					
						
							| 
									
										
										
										
											2014-09-24 11:39:17 +02:00
										 |  |  | 	bi.TD = decoder.Get(3).BigInt() | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (bi *BlockInfo) RlpEncode() []byte { | 
					
						
							| 
									
										
										
										
											2014-09-24 11:39:17 +02:00
										 |  |  | 	return ethutil.Encode([]interface{}{bi.Number, bi.Hash, bi.Parent, bi.TD}) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-15 01:11:01 +02:00
										 |  |  | type Blocks []*Block | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self Blocks) AsSet() ethutil.UniqueSet { | 
					
						
							|  |  |  | 	set := make(ethutil.UniqueSet) | 
					
						
							|  |  |  | 	for _, block := range self { | 
					
						
							|  |  |  | 		set.Insert(block.Hash()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return set | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | type BlockBy func(b1, b2 *Block) bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self BlockBy) Sort(blocks Blocks) { | 
					
						
							|  |  |  | 	bs := blockSorter{ | 
					
						
							|  |  |  | 		blocks: blocks, | 
					
						
							|  |  |  | 		by:     self, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sort.Sort(bs) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type blockSorter struct { | 
					
						
							|  |  |  | 	blocks Blocks | 
					
						
							|  |  |  | 	by     func(b1, b2 *Block) bool | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self blockSorter) Len() int { return len(self.blocks) } | 
					
						
							|  |  |  | func (self blockSorter) Swap(i, j int) { | 
					
						
							|  |  |  | 	self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Number(b1, b2 *Block) bool { return b1.Number.Cmp(b2.Number) < 0 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | type Block struct { | 
					
						
							|  |  |  | 	// Hash to the previous block | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | 	PrevHash ethutil.Bytes | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	// Uncles of this block | 
					
						
							| 
									
										
										
										
											2014-09-15 01:11:01 +02:00
										 |  |  | 	Uncles   Blocks | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	UncleSha []byte | 
					
						
							|  |  |  | 	// The coin base address | 
					
						
							|  |  |  | 	Coinbase []byte | 
					
						
							|  |  |  | 	// Block Trie state | 
					
						
							| 
									
										
										
										
											2014-03-02 20:42:05 +01:00
										 |  |  | 	//state *ethutil.Trie | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 	state *ethstate.State | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	// Difficulty for the current block | 
					
						
							|  |  |  | 	Difficulty *big.Int | 
					
						
							|  |  |  | 	// Creation time | 
					
						
							|  |  |  | 	Time int64 | 
					
						
							| 
									
										
										
										
											2014-05-20 14:29:52 +02:00
										 |  |  | 	// The block number | 
					
						
							|  |  |  | 	Number *big.Int | 
					
						
							|  |  |  | 	// Minimum Gas Price | 
					
						
							|  |  |  | 	MinGasPrice *big.Int | 
					
						
							|  |  |  | 	// Gas limit | 
					
						
							|  |  |  | 	GasLimit *big.Int | 
					
						
							|  |  |  | 	// Gas used | 
					
						
							|  |  |  | 	GasUsed *big.Int | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	// Extra data | 
					
						
							|  |  |  | 	Extra string | 
					
						
							|  |  |  | 	// Block Nonce for verification | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | 	Nonce ethutil.Bytes | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	// List of transactions and/or contracts | 
					
						
							|  |  |  | 	transactions []*Transaction | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	receipts     []*Receipt | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	TxSha        []byte | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewBlockFromBytes(raw []byte) *Block { | 
					
						
							|  |  |  | 	block := &Block{} | 
					
						
							|  |  |  | 	block.RlpDecode(raw) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return block | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // New block takes a raw encoded string | 
					
						
							|  |  |  | func NewBlockFromRlpValue(rlpValue *ethutil.Value) *Block { | 
					
						
							|  |  |  | 	block := &Block{} | 
					
						
							|  |  |  | 	block.RlpValueDecode(rlpValue) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return block | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func CreateBlock(root interface{}, | 
					
						
							|  |  |  | 	prevHash []byte, | 
					
						
							|  |  |  | 	base []byte, | 
					
						
							|  |  |  | 	Difficulty *big.Int, | 
					
						
							|  |  |  | 	Nonce []byte, | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	extra string) *Block { | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	block := &Block{ | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 		PrevHash:    prevHash, | 
					
						
							|  |  |  | 		Coinbase:    base, | 
					
						
							|  |  |  | 		Difficulty:  Difficulty, | 
					
						
							|  |  |  | 		Nonce:       Nonce, | 
					
						
							|  |  |  | 		Time:        time.Now().Unix(), | 
					
						
							|  |  |  | 		Extra:       extra, | 
					
						
							|  |  |  | 		UncleSha:    EmptyShaList, | 
					
						
							|  |  |  | 		GasUsed:     new(big.Int), | 
					
						
							|  |  |  | 		MinGasPrice: new(big.Int), | 
					
						
							|  |  |  | 		GasLimit:    new(big.Int), | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	block.SetUncles([]*Block{}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-04 10:42:40 +02:00
										 |  |  | 	block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, root)) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return block | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Returns a hash of the block | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | func (block *Block) Hash() ethutil.Bytes { | 
					
						
							| 
									
										
										
										
											2014-10-08 12:06:39 +02:00
										 |  |  | 	return ethcrypto.Sha3(ethutil.NewValue(block.header()).Encode()) | 
					
						
							|  |  |  | 	//return ethcrypto.Sha3(block.Value().Encode()) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) HashNoNonce() []byte { | 
					
						
							| 
									
										
										
										
											2014-10-08 12:06:39 +02:00
										 |  |  | 	return ethcrypto.Sha3(ethutil.Encode([]interface{}{block.PrevHash, | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 		block.UncleSha, block.Coinbase, block.state.Trie.Root, | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 		block.TxSha, block.Difficulty, block.Number, block.MinGasPrice, | 
					
						
							|  |  |  | 		block.GasLimit, block.GasUsed, block.Time, block.Extra})) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | func (block *Block) State() *ethstate.State { | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	return block.state | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) Transactions() []*Transaction { | 
					
						
							|  |  |  | 	return block.transactions | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-10 17:22:06 +02:00
										 |  |  | func (block *Block) CalcGasLimit(parent *Block) *big.Int { | 
					
						
							| 
									
										
										
										
											2014-06-11 16:16:57 +02:00
										 |  |  | 	if block.Number.Cmp(big.NewInt(0)) == 0 { | 
					
						
							| 
									
										
										
										
											2014-06-10 17:22:06 +02:00
										 |  |  | 		return ethutil.BigPow(10, 6) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-11 16:16:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-09 18:06:16 +01:00
										 |  |  | 	// ((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)) | 
					
						
							| 
									
										
										
										
											2014-06-10 17:22:06 +02:00
										 |  |  | 	curInt := new(big.Int).Div(current.Num(), current.Denom()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	result := new(big.Int).Add(previous, curInt) | 
					
						
							|  |  |  | 	result.Div(result, big.NewInt(1024)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 15:25:57 +02:00
										 |  |  | 	min := big.NewInt(125000) | 
					
						
							| 
									
										
										
										
											2014-06-10 17:22:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ethutil.BigMax(min, result) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | func (block *Block) BlockInfo() BlockInfo { | 
					
						
							|  |  |  | 	bi := BlockInfo{} | 
					
						
							|  |  |  | 	data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...)) | 
					
						
							|  |  |  | 	bi.RlpDecode(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return bi | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-22 17:56:33 +02:00
										 |  |  | func (self *Block) GetTransaction(hash []byte) *Transaction { | 
					
						
							|  |  |  | 	for _, receipt := range self.receipts { | 
					
						
							|  |  |  | 		if bytes.Compare(receipt.Tx.Hash(), hash) == 0 { | 
					
						
							|  |  |  | 			return receipt.Tx | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:35:17 +01:00
										 |  |  | // Sync the block's state and contract respectively | 
					
						
							|  |  |  | func (block *Block) Sync() { | 
					
						
							| 
									
										
										
										
											2014-03-03 11:03:16 +01:00
										 |  |  | 	block.state.Sync() | 
					
						
							| 
									
										
										
										
											2014-02-19 11:35:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) Undo() { | 
					
						
							|  |  |  | 	// Sync the block state itself | 
					
						
							| 
									
										
										
										
											2014-03-02 20:42:05 +01:00
										 |  |  | 	block.state.Reset() | 
					
						
							| 
									
										
										
										
											2014-02-19 11:35:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | /////// Block Encoding | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | func (block *Block) rlpReceipts() interface{} { | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	// Marshal the transactions of this block | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	encR := make([]interface{}, len(block.receipts)) | 
					
						
							|  |  |  | 	for i, r := range block.receipts { | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 		// Cast it to a string (safe) | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 		encR[i] = r.RlpData() | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	return encR | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) rlpUncles() interface{} { | 
					
						
							|  |  |  | 	// Marshal the transactions of this block | 
					
						
							|  |  |  | 	uncles := make([]interface{}, len(block.Uncles)) | 
					
						
							|  |  |  | 	for i, uncle := range block.Uncles { | 
					
						
							|  |  |  | 		// Cast it to a string (safe) | 
					
						
							|  |  |  | 		uncles[i] = uncle.header() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return uncles | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) SetUncles(uncles []*Block) { | 
					
						
							|  |  |  | 	block.Uncles = uncles | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Sha of the concatenated uncles | 
					
						
							| 
									
										
										
										
											2014-10-08 12:06:39 +02:00
										 |  |  | 	block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles())) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) { | 
					
						
							|  |  |  | 	self.receipts = receipts | 
					
						
							|  |  |  | 	self.setTransactions(txs) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) setTransactions(txs []*Transaction) { | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	block.transactions = txs | 
					
						
							| 
									
										
										
										
											2014-07-21 12:21:34 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func CreateTxSha(receipts Receipts) (sha []byte) { | 
					
						
							| 
									
										
										
										
											2014-08-04 10:38:18 +02:00
										 |  |  | 	trie := ethtrie.New(ethutil.Config.Db, "") | 
					
						
							| 
									
										
										
										
											2014-07-21 12:21:34 +02:00
										 |  |  | 	for i, receipt := range receipts { | 
					
						
							|  |  |  | 		trie.Update(string(ethutil.NewValue(i).Encode()), string(ethutil.NewValue(receipt.RlpData()).Encode())) | 
					
						
							| 
									
										
										
										
											2014-05-20 15:02:46 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:04:47 +02:00
										 |  |  | 	switch trie.Root.(type) { | 
					
						
							|  |  |  | 	case string: | 
					
						
							| 
									
										
										
										
											2014-07-21 12:21:34 +02:00
										 |  |  | 		sha = []byte(trie.Root.(string)) | 
					
						
							| 
									
										
										
										
											2014-05-20 22:04:47 +02:00
										 |  |  | 	case []byte: | 
					
						
							| 
									
										
										
										
											2014-07-21 12:21:34 +02:00
										 |  |  | 		sha = trie.Root.([]byte) | 
					
						
							| 
									
										
										
										
											2014-05-20 22:04:47 +02:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		panic(fmt.Sprintf("invalid root type %T", trie.Root)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-21 12:21:34 +02:00
										 |  |  | 	return sha | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Block) SetTxHash(receipts Receipts) { | 
					
						
							|  |  |  | 	self.TxSha = CreateTxSha(receipts) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 01:34:18 +01:00
										 |  |  | func (block *Block) Value() *ethutil.Value { | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	return ethutil.NewValue([]interface{}{block.header(), block.rlpReceipts(), block.rlpUncles()}) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) RlpEncode() []byte { | 
					
						
							|  |  |  | 	// Encode a slice interface which contains the header and the list of | 
					
						
							|  |  |  | 	// transactions. | 
					
						
							| 
									
										
										
										
											2014-02-15 01:34:18 +01:00
										 |  |  | 	return block.Value().Encode() | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) RlpDecode(data []byte) { | 
					
						
							|  |  |  | 	rlpValue := ethutil.NewValueFromBytes(data) | 
					
						
							|  |  |  | 	block.RlpValueDecode(rlpValue) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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() | 
					
						
							| 
									
										
										
										
											2014-08-04 10:42:40 +02:00
										 |  |  | 	block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	block.TxSha = header.Get(4).Bytes() | 
					
						
							|  |  |  | 	block.Difficulty = header.Get(5).BigInt() | 
					
						
							| 
									
										
										
										
											2014-05-20 14:29:52 +02:00
										 |  |  | 	block.Number = header.Get(6).BigInt() | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	//fmt.Printf("#%v : %x\n", block.Number, block.Coinbase) | 
					
						
							| 
									
										
										
										
											2014-05-20 14:29:52 +02:00
										 |  |  | 	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() | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Tx list might be empty if this is an uncle. Uncles only have their | 
					
						
							|  |  |  | 	// header set. | 
					
						
							|  |  |  | 	if decoder.Get(1).IsNil() == false { // Yes explicitness | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if decoder.Get(2).IsNil() == false { // Yes explicitness | 
					
						
							|  |  |  | 		uncles := decoder.Get(2) | 
					
						
							|  |  |  | 		block.Uncles = make([]*Block, uncles.Len()) | 
					
						
							|  |  |  | 		for i := 0; i < uncles.Len(); i++ { | 
					
						
							|  |  |  | 			block.Uncles[i] = NewUncleBlockFromValue(uncles.Get(i)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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() | 
					
						
							| 
									
										
										
										
											2014-08-04 10:42:40 +02:00
										 |  |  | 	block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, header.Get(3).Val)) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	block.TxSha = header.Get(4).Bytes() | 
					
						
							|  |  |  | 	block.Difficulty = header.Get(5).BigInt() | 
					
						
							| 
									
										
										
										
											2014-05-20 14:29:52 +02:00
										 |  |  | 	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() | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return block | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-11 00:41:37 +02:00
										 |  |  | func (block *Block) Trie() *ethtrie.Trie { | 
					
						
							| 
									
										
										
										
											2014-10-10 22:42:37 +02:00
										 |  |  | 	return block.state.Trie | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-20 11:20:29 +01:00
										 |  |  | func (block *Block) GetRoot() interface{} { | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 	return block.state.Trie.Root | 
					
						
							| 
									
										
										
										
											2014-03-20 11:20:29 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 22:42:37 +02:00
										 |  |  | func (block *Block) Diff() *big.Int { | 
					
						
							|  |  |  | 	return block.Difficulty | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | func (self *Block) Receipts() []*Receipt { | 
					
						
							|  |  |  | 	return self.receipts | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | func (block *Block) header() []interface{} { | 
					
						
							|  |  |  | 	return []interface{}{ | 
					
						
							|  |  |  | 		// Sha of the previous block | 
					
						
							|  |  |  | 		block.PrevHash, | 
					
						
							|  |  |  | 		// Sha of uncles | 
					
						
							|  |  |  | 		block.UncleSha, | 
					
						
							|  |  |  | 		// Coinbase address | 
					
						
							|  |  |  | 		block.Coinbase, | 
					
						
							|  |  |  | 		// root state | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 		block.state.Trie.Root, | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 		// Sha of tx | 
					
						
							|  |  |  | 		block.TxSha, | 
					
						
							|  |  |  | 		// Current block Difficulty | 
					
						
							|  |  |  | 		block.Difficulty, | 
					
						
							| 
									
										
										
										
											2014-05-20 14:29:52 +02:00
										 |  |  | 		// The block number | 
					
						
							|  |  |  | 		block.Number, | 
					
						
							|  |  |  | 		// Block minimum gas price | 
					
						
							|  |  |  | 		block.MinGasPrice, | 
					
						
							|  |  |  | 		// Block upper gas bound | 
					
						
							|  |  |  | 		block.GasLimit, | 
					
						
							|  |  |  | 		// Block gas used | 
					
						
							|  |  |  | 		block.GasUsed, | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 		// Time the block was found? | 
					
						
							|  |  |  | 		block.Time, | 
					
						
							|  |  |  | 		// Extra data | 
					
						
							|  |  |  | 		block.Extra, | 
					
						
							|  |  |  | 		// Block's Nonce for validation | 
					
						
							|  |  |  | 		block.Nonce, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-20 15:02:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (block *Block) String() string { | 
					
						
							|  |  |  | 	return fmt.Sprintf(` | 
					
						
							| 
									
										
										
										
											2014-08-25 12:53:06 +02:00
										 |  |  | 	BLOCK(%x): Size: %v | 
					
						
							| 
									
										
										
										
											2014-05-20 15:02:46 +02:00
										 |  |  | 	PrevHash:   %x | 
					
						
							|  |  |  | 	UncleSha:   %x | 
					
						
							|  |  |  | 	Coinbase:   %x | 
					
						
							|  |  |  | 	Root:       %x | 
					
						
							|  |  |  | 	TxSha:      %x | 
					
						
							|  |  |  | 	Difficulty: %v | 
					
						
							|  |  |  | 	Number:     %v | 
					
						
							|  |  |  | 	MinGas:     %v | 
					
						
							|  |  |  | 	MaxLimit:   %v | 
					
						
							|  |  |  | 	GasUsed:    %v | 
					
						
							|  |  |  | 	Time:       %v | 
					
						
							|  |  |  | 	Extra:      %v | 
					
						
							|  |  |  | 	Nonce:      %x | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	NumTx:      %v | 
					
						
							| 
									
										
										
										
											2014-05-20 15:02:46 +02:00
										 |  |  | `, | 
					
						
							|  |  |  | 		block.Hash(), | 
					
						
							| 
									
										
										
										
											2014-08-25 12:53:06 +02:00
										 |  |  | 		block.Size(), | 
					
						
							| 
									
										
										
										
											2014-05-20 15:02:46 +02:00
										 |  |  | 		block.PrevHash, | 
					
						
							|  |  |  | 		block.UncleSha, | 
					
						
							|  |  |  | 		block.Coinbase, | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 		block.state.Trie.Root, | 
					
						
							| 
									
										
										
										
											2014-05-20 15:02:46 +02:00
										 |  |  | 		block.TxSha, | 
					
						
							|  |  |  | 		block.Difficulty, | 
					
						
							|  |  |  | 		block.Number, | 
					
						
							|  |  |  | 		block.MinGasPrice, | 
					
						
							|  |  |  | 		block.GasLimit, | 
					
						
							|  |  |  | 		block.GasUsed, | 
					
						
							|  |  |  | 		block.Time, | 
					
						
							|  |  |  | 		block.Extra, | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 		block.Nonce, | 
					
						
							|  |  |  | 		len(block.transactions), | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2014-05-20 15:02:46 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-08-25 12:53:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (self *Block) Size() ethutil.StorageSize { | 
					
						
							|  |  |  | 	return ethutil.StorageSize(len(self.RlpEncode())) | 
					
						
							|  |  |  | } |