block.go 10.7 KB
Newer Older
1
package types
O
obscuren 已提交
2 3

import (
4
	"bytes"
O
obscuren 已提交
5
	"encoding/binary"
6
	"encoding/json"
O
obscuren 已提交
7
	"fmt"
8
	"io"
O
obscuren 已提交
9
	"math/big"
O
obscuren 已提交
10
	"sort"
O
obscuren 已提交
11
	"time"
O
obscuren 已提交
12

O
obscuren 已提交
13
	"github.com/ethereum/go-ethereum/common"
14
	"github.com/ethereum/go-ethereum/crypto/sha3"
O
obscuren 已提交
15
	"github.com/ethereum/go-ethereum/rlp"
O
obscuren 已提交
16 17
)

O
obscuren 已提交
18
type Header struct {
O
obscuren 已提交
19
	// Hash to the previous block
O
obscuren 已提交
20
	ParentHash common.Hash
O
obscuren 已提交
21
	// Uncles of this block
O
obscuren 已提交
22
	UncleHash common.Hash
O
obscuren 已提交
23
	// The coin base address
O
obscuren 已提交
24
	Coinbase common.Address
O
obscuren 已提交
25
	// Block Trie state
O
obscuren 已提交
26
	Root common.Hash
O
obscuren 已提交
27
	// Tx sha
O
obscuren 已提交
28
	TxHash common.Hash
O
obscuren 已提交
29
	// Receipt sha
O
obscuren 已提交
30
	ReceiptHash common.Hash
O
obscuren 已提交
31
	// Bloom
O
obscuren 已提交
32
	Bloom Bloom
O
obscuren 已提交
33 34
	// Difficulty for the current block
	Difficulty *big.Int
O
obscuren 已提交
35 36 37 38 39 40
	// The block number
	Number *big.Int
	// Gas limit
	GasLimit *big.Int
	// Gas used
	GasUsed *big.Int
O
obscuren 已提交
41 42
	// Creation time
	Time uint64
O
obscuren 已提交
43
	// Extra data
44
	Extra []byte
45
	// Mix digest for quick checking to prevent DOS
O
obscuren 已提交
46
	MixDigest common.Hash
47
	// Nonce
O
obscuren 已提交
48
	Nonce [8]byte
O
obscuren 已提交
49 50
}

51 52 53 54 55 56 57 58
func (self *Header) Hash() common.Hash {
	return rlpHash(self.rlpData(true))
}

func (self *Header) HashNoNonce() common.Hash {
	return rlpHash(self.rlpData(false))
}

O
obscuren 已提交
59
func (self *Header) rlpData(withNonce bool) []interface{} {
M
Matthew Wampler-Doty 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72
	fields := []interface{}{
		self.ParentHash,
		self.UncleHash,
		self.Coinbase,
		self.Root,
		self.TxHash,
		self.ReceiptHash,
		self.Bloom,
		self.Difficulty,
		self.Number,
		self.GasLimit,
		self.GasUsed,
		self.Time,
73 74
		self.Extra,
	}
O
obscuren 已提交
75
	if withNonce {
76
		fields = append(fields, self.MixDigest, self.Nonce)
O
obscuren 已提交
77 78 79 80 81 82
	}
	return fields
}

func (self *Header) RlpData() interface{} {
	return self.rlpData(true)
O
obscuren 已提交
83 84
}

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
func (h *Header) UnmarshalJSON(data []byte) error {
	var ext struct {
		ParentHash string
		Coinbase   string
		Difficulty string
		GasLimit   string
		Time       uint64
		Extra      string
	}
	dec := json.NewDecoder(bytes.NewReader(data))
	if err := dec.Decode(&ext); err != nil {
		return err
	}

	h.ParentHash = common.HexToHash(ext.ParentHash)
	h.Coinbase = common.HexToAddress(ext.Coinbase)
	h.Difficulty = common.String2Big(ext.Difficulty)
	h.Time = ext.Time
	h.Extra = []byte(ext.Extra)
	return nil
}

107 108 109 110 111
func rlpHash(x interface{}) (h common.Hash) {
	hw := sha3.NewKeccak256()
	rlp.Encode(hw, x)
	hw.Sum(h[:0])
	return h
O
obscuren 已提交
112 113
}

O
obscuren 已提交
114
type Block struct {
O
obscuren 已提交
115 116 117 118 119 120 121 122 123
	// Preset Hash for mock (Tests)
	HeaderHash       common.Hash
	ParentHeaderHash common.Hash
	// ^^^^ ignore ^^^^

	header       *Header
	uncles       []*Header
	transactions Transactions
	Td           *big.Int
Z
zelig 已提交
124
	queued       bool // flag for blockpool to skip TD check
O
obscuren 已提交
125

126 127
	ReceivedAt time.Time

O
obscuren 已提交
128 129 130
	receipts Receipts
}

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
// StorageBlock defines the RLP encoding of a Block stored in the
// state database. The StorageBlock encoding contains fields that
// would otherwise need to be recomputed.
type StorageBlock Block

// "external" block encoding. used for eth protocol, etc.
type extblock struct {
	Header *Header
	Txs    []*Transaction
	Uncles []*Header
}

// "storage" block encoding. used for database.
type storageblock struct {
	Header *Header
	Txs    []*Transaction
	Uncles []*Header
	TD     *big.Int
}

151
func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash, difficulty *big.Int, nonce uint64, extra []byte) *Block {
O
obscuren 已提交
152 153 154 155 156 157
	header := &Header{
		Root:       root,
		ParentHash: parentHash,
		Coinbase:   coinbase,
		Difficulty: difficulty,
		Time:       uint64(time.Now().Unix()),
O
obscuren 已提交
158 159 160
		Extra:      extra,
		GasUsed:    new(big.Int),
		GasLimit:   new(big.Int),
O
obscuren 已提交
161
		Number:     new(big.Int),
O
obscuren 已提交
162
	}
O
obscuren 已提交
163
	header.SetNonce(nonce)
O
obscuren 已提交
164
	block := &Block{header: header}
O
obscuren 已提交
165 166
	block.Td = new(big.Int)

O
obscuren 已提交
167 168 169
	return block
}

O
obscuren 已提交
170
func (self *Header) SetNonce(nonce uint64) {
O
obscuren 已提交
171
	binary.BigEndian.PutUint64(self.Nonce[:], nonce)
O
obscuren 已提交
172 173
}

O
obscuren 已提交
174 175
func NewBlockWithHeader(header *Header) *Block {
	return &Block{header: header}
O
obscuren 已提交
176 177
}

178
func (self *Block) ValidateFields() error {
179 180 181
	if self.header == nil {
		return fmt.Errorf("header is nil")
	}
182 183 184 185
	for i, transaction := range self.transactions {
		if transaction == nil {
			return fmt.Errorf("transaction %d is nil", i)
		}
186
	}
187 188 189 190
	for i, uncle := range self.uncles {
		if uncle == nil {
			return fmt.Errorf("uncle %d is nil", i)
		}
191 192 193 194
	}
	return nil
}

O
obscuren 已提交
195
func (self *Block) DecodeRLP(s *rlp.Stream) error {
196 197 198
	var eb extblock
	if err := s.Decode(&eb); err != nil {
		return err
O
obscuren 已提交
199
	}
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
	self.header, self.uncles, self.transactions = eb.Header, eb.Uncles, eb.Txs
	return nil
}

func (self Block) EncodeRLP(w io.Writer) error {
	return rlp.Encode(w, extblock{
		Header: self.header,
		Txs:    self.transactions,
		Uncles: self.uncles,
	})
}

func (self *StorageBlock) DecodeRLP(s *rlp.Stream) error {
	var sb storageblock
	if err := s.Decode(&sb); err != nil {
O
obscuren 已提交
215 216
		return err
	}
217
	self.header, self.uncles, self.transactions, self.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
O
obscuren 已提交
218
	return nil
O
obscuren 已提交
219 220
}

221 222 223 224 225 226 227 228 229
func (self StorageBlock) EncodeRLP(w io.Writer) error {
	return rlp.Encode(w, storageblock{
		Header: self.header,
		Txs:    self.transactions,
		Uncles: self.uncles,
		TD:     self.Td,
	})
}

O
obscuren 已提交
230 231
func (self *Block) Header() *Header {
	return self.header
O
obscuren 已提交
232 233
}

O
obscuren 已提交
234 235
func (self *Block) Uncles() []*Header {
	return self.uncles
O
obscuren 已提交
236 237
}

238 239 240 241
func (self *Block) CalculateUnclesHash() common.Hash {
	return rlpHash(self.uncles)
}

O
obscuren 已提交
242 243
func (self *Block) SetUncles(uncleHeaders []*Header) {
	self.uncles = uncleHeaders
244
	self.header.UncleHash = rlpHash(uncleHeaders)
O
obscuren 已提交
245 246
}

O
obscuren 已提交
247 248
func (self *Block) Transactions() Transactions {
	return self.transactions
O
obscuren 已提交
249 250
}

251
func (self *Block) Transaction(hash common.Hash) *Transaction {
O
obscuren 已提交
252
	for _, transaction := range self.transactions {
253
		if transaction.Hash() == hash {
O
obscuren 已提交
254
			return transaction
O
obscuren 已提交
255 256
		}
	}
O
obscuren 已提交
257
	return nil
O
obscuren 已提交
258 259
}

O
obscuren 已提交
260 261 262
func (self *Block) SetTransactions(transactions Transactions) {
	self.transactions = transactions
	self.header.TxHash = DeriveSha(transactions)
O
obscuren 已提交
263
}
O
obscuren 已提交
264 265 266 267
func (self *Block) AddTransaction(transaction *Transaction) {
	self.transactions = append(self.transactions, transaction)
	self.SetTransactions(self.transactions)
}
O
obscuren 已提交
268

O
obscuren 已提交
269 270
func (self *Block) Receipts() Receipts {
	return self.receipts
O
obscuren 已提交
271 272
}

O
obscuren 已提交
273 274 275 276
func (self *Block) SetReceipts(receipts Receipts) {
	self.receipts = receipts
	self.header.ReceiptHash = DeriveSha(receipts)
	self.header.Bloom = CreateBloom(receipts)
277
}
O
obscuren 已提交
278 279 280 281
func (self *Block) AddReceipt(receipt *Receipt) {
	self.receipts = append(self.receipts, receipt)
	self.SetReceipts(self.receipts)
}
282

O
obscuren 已提交
283
func (self *Block) RlpData() interface{} {
Z
zelig 已提交
284 285
	return []interface{}{self.header, self.transactions, self.uncles}
}
O
obscuren 已提交
286

Z
zelig 已提交
287
func (self *Block) RlpDataForStorage() interface{} {
O
obscuren 已提交
288 289 290 291
	return []interface{}{self.header, self.transactions, self.uncles, self.Td /* TODO receipts */}
}

// Header accessors (add as you need them)
O
obscuren 已提交
292 293 294
func (self *Block) Number() *big.Int       { return self.header.Number }
func (self *Block) NumberU64() uint64      { return self.header.Number.Uint64() }
func (self *Block) MixDigest() common.Hash { return self.header.MixDigest }
O
obscuren 已提交
295
func (self *Block) Nonce() uint64 {
O
obscuren 已提交
296
	return binary.BigEndian.Uint64(self.header.Nonce[:])
O
obscuren 已提交
297 298
}
func (self *Block) SetNonce(nonce uint64) {
O
obscuren 已提交
299
	self.header.SetNonce(nonce)
O
obscuren 已提交
300 301
}

Z
zelig 已提交
302 303 304
func (self *Block) Queued() bool     { return self.queued }
func (self *Block) SetQueued(q bool) { self.queued = q }

O
obscuren 已提交
305 306
func (self *Block) Bloom() Bloom             { return self.header.Bloom }
func (self *Block) Coinbase() common.Address { return self.header.Coinbase }
O
obscuren 已提交
307 308 309
func (self *Block) Time() int64              { return int64(self.header.Time) }
func (self *Block) GasLimit() *big.Int       { return self.header.GasLimit }
func (self *Block) GasUsed() *big.Int        { return self.header.GasUsed }
O
obscuren 已提交
310 311
func (self *Block) Root() common.Hash        { return self.header.Root }
func (self *Block) SetRoot(root common.Hash) { self.header.Root = root }
312 313 314 315 316 317 318 319 320 321 322 323
func (self *Block) GetTransaction(i int) *Transaction {
	if len(self.transactions) > i {
		return self.transactions[i]
	}
	return nil
}
func (self *Block) GetUncle(i int) *Header {
	if len(self.uncles) > i {
		return self.uncles[i]
	}
	return nil
}
O
obscuren 已提交
324

325 326 327 328 329 330 331 332 333 334 335 336 337
func (self *Block) Size() common.StorageSize {
	c := writeCounter(0)
	rlp.Encode(&c, self)
	return common.StorageSize(c)
}

type writeCounter common.StorageSize

func (c *writeCounter) Write(b []byte) (int, error) {
	*c += writeCounter(len(b))
	return len(b), nil
}

O
Merge  
obscuren 已提交
338
// Implement pow.Block
O
obscuren 已提交
339 340
func (self *Block) Difficulty() *big.Int     { return self.header.Difficulty }
func (self *Block) HashNoNonce() common.Hash { return self.header.HashNoNonce() }
O
Merge  
obscuren 已提交
341

O
obscuren 已提交
342 343
func (self *Block) Hash() common.Hash {
	if (self.HeaderHash != common.Hash{}) {
O
Merge  
obscuren 已提交
344 345 346 347 348 349
		return self.HeaderHash
	} else {
		return self.header.Hash()
	}
}

O
obscuren 已提交
350 351
func (self *Block) ParentHash() common.Hash {
	if (self.ParentHeaderHash != common.Hash{}) {
O
Merge  
obscuren 已提交
352 353 354 355
		return self.ParentHeaderHash
	} else {
		return self.header.ParentHash
	}
O
obscuren 已提交
356 357
}

O
obscuren 已提交
358
func (self *Block) Copy() *Block {
O
obscuren 已提交
359
	block := NewBlock(self.header.ParentHash, self.Coinbase(), self.Root(), new(big.Int), self.Nonce(), self.header.Extra)
O
obscuren 已提交
360 361 362 363 364 365 366 367 368
	block.header.Bloom = self.header.Bloom
	block.header.TxHash = self.header.TxHash
	block.transactions = self.transactions
	block.header.UncleHash = self.header.UncleHash
	block.uncles = self.uncles
	block.header.GasLimit.Set(self.header.GasLimit)
	block.header.GasUsed.Set(self.header.GasUsed)
	block.header.ReceiptHash = self.header.ReceiptHash
	block.header.Difficulty.Set(self.header.Difficulty)
O
obscuren 已提交
369
	block.header.Number.Set(self.header.Number)
O
obscuren 已提交
370 371
	block.header.Time = self.header.Time
	block.header.MixDigest = self.header.MixDigest
O
obscuren 已提交
372 373 374 375
	if self.Td != nil {
		block.Td.Set(self.Td)
	}

O
obscuren 已提交
376 377 378
	return block
}

O
obscuren 已提交
379
func (self *Block) String() string {
380
	str := fmt.Sprintf(`Block(#%v): Size: %v TD: %v {
381
MinerHash: %x
O
obscuren 已提交
382
%v
O
obscuren 已提交
383
Transactions:
O
obscuren 已提交
384
%v
O
obscuren 已提交
385
Uncles:
O
obscuren 已提交
386 387
%v
}
388
`, self.Number(), self.Size(), self.Td, self.header.HashNoNonce(), self.header, self.transactions, self.uncles)
389 390 391 392 393 394 395 396 397 398

	if (self.HeaderHash != common.Hash{}) {
		str += fmt.Sprintf("\nFake hash = %x", self.HeaderHash)
	}

	if (self.ParentHeaderHash != common.Hash{}) {
		str += fmt.Sprintf("\nFake parent hash = %x", self.ParentHeaderHash)
	}

	return str
O
obscuren 已提交
399 400 401
}

func (self *Header) String() string {
402 403
	return fmt.Sprintf(`Header(%x):
[
O
obscuren 已提交
404 405 406 407 408 409 410 411 412 413 414 415
	ParentHash:	    %x
	UncleHash:	    %x
	Coinbase:	    %x
	Root:		    %x
	TxSha		    %x
	ReceiptSha:	    %x
	Bloom:		    %x
	Difficulty:	    %v
	Number:		    %v
	GasLimit:	    %v
	GasUsed:	    %v
	Time:		    %v
416
	Extra:		    %s
O
obscuren 已提交
417
	MixDigest:          %x
418 419
	Nonce:		    %x
]`, self.Hash(), self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra, self.MixDigest, self.Nonce)
M
Maran 已提交
420
}
O
obscuren 已提交
421

O
obscuren 已提交
422
type Blocks []*Block
423

O
obscuren 已提交
424
type BlockBy func(b1, b2 *Block) bool
O
obscuren 已提交
425

O
obscuren 已提交
426 427 428 429
func (self BlockBy) Sort(blocks Blocks) {
	bs := blockSorter{
		blocks: blocks,
		by:     self,
O
obscuren 已提交
430
	}
O
obscuren 已提交
431
	sort.Sort(bs)
O
obscuren 已提交
432
}
O
obscuren 已提交
433

O
obscuren 已提交
434 435 436
type blockSorter struct {
	blocks Blocks
	by     func(b1, b2 *Block) bool
O
obscuren 已提交
437
}
O
obscuren 已提交
438

O
obscuren 已提交
439 440 441
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]
O
obscuren 已提交
442
}
O
obscuren 已提交
443
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
O
obscuren 已提交
444

O
obscuren 已提交
445
func Number(b1, b2 *Block) bool { return b1.Header().Number.Cmp(b2.Header().Number) < 0 }