github.com/immesys/bw2bc@v1.1.0/core/types/block.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package types contains data types related to Ethereum consensus. 18 package types 19 20 import ( 21 "bytes" 22 "encoding/binary" 23 "encoding/json" 24 "fmt" 25 "io" 26 "math/big" 27 "sort" 28 "sync/atomic" 29 "time" 30 31 "github.com/ethereum/go-ethereum/common" 32 "github.com/ethereum/go-ethereum/crypto/sha3" 33 "github.com/ethereum/go-ethereum/rlp" 34 ) 35 36 // A BlockNonce is a 64-bit hash which proves (combined with the 37 // mix-hash) that a suffcient amount of computation has been carried 38 // out on a block. 39 type BlockNonce [8]byte 40 41 func EncodeNonce(i uint64) BlockNonce { 42 var n BlockNonce 43 binary.BigEndian.PutUint64(n[:], i) 44 return n 45 } 46 47 func (n BlockNonce) Uint64() uint64 { 48 return binary.BigEndian.Uint64(n[:]) 49 } 50 51 type Header struct { 52 ParentHash common.Hash // Hash to the previous block 53 UncleHash common.Hash // Uncles of this block 54 Coinbase common.Address // The coin base address 55 Root common.Hash // Block Trie state 56 TxHash common.Hash // Tx sha 57 ReceiptHash common.Hash // Receipt sha 58 Bloom Bloom // Bloom 59 Difficulty *big.Int // Difficulty for the current block 60 Number *big.Int // The block number 61 GasLimit *big.Int // Gas limit 62 GasUsed *big.Int // Gas used 63 Time *big.Int // Creation time 64 Extra []byte // Extra data 65 MixDigest common.Hash // for quick difficulty verification 66 Nonce BlockNonce 67 } 68 69 func (h *Header) Hash() common.Hash { 70 return rlpHash(h) 71 } 72 73 func (h *Header) HashNoNonce() common.Hash { 74 return rlpHash([]interface{}{ 75 h.ParentHash, 76 h.UncleHash, 77 h.Coinbase, 78 h.Root, 79 h.TxHash, 80 h.ReceiptHash, 81 h.Bloom, 82 h.Difficulty, 83 h.Number, 84 h.GasLimit, 85 h.GasUsed, 86 h.Time, 87 h.Extra, 88 }) 89 } 90 91 func (h *Header) UnmarshalJSON(data []byte) error { 92 var ext struct { 93 ParentHash string 94 Coinbase string 95 Difficulty string 96 GasLimit string 97 Time *big.Int 98 Extra string 99 } 100 dec := json.NewDecoder(bytes.NewReader(data)) 101 if err := dec.Decode(&ext); err != nil { 102 return err 103 } 104 105 h.ParentHash = common.HexToHash(ext.ParentHash) 106 h.Coinbase = common.HexToAddress(ext.Coinbase) 107 h.Difficulty = common.String2Big(ext.Difficulty) 108 h.Time = ext.Time 109 h.Extra = []byte(ext.Extra) 110 return nil 111 } 112 113 func rlpHash(x interface{}) (h common.Hash) { 114 hw := sha3.NewKeccak256() 115 rlp.Encode(hw, x) 116 hw.Sum(h[:0]) 117 return h 118 } 119 120 type Block struct { 121 header *Header 122 uncles []*Header 123 transactions Transactions 124 receipts Receipts 125 126 // caches 127 hash atomic.Value 128 size atomic.Value 129 130 // Td is used by package core to store the total difficulty 131 // of the chain up to and including the block. 132 Td *big.Int 133 134 // ReceivedAt is used by package eth to track block propagation time. 135 ReceivedAt time.Time 136 } 137 138 // StorageBlock defines the RLP encoding of a Block stored in the 139 // state database. The StorageBlock encoding contains fields that 140 // would otherwise need to be recomputed. 141 type StorageBlock Block 142 143 // "external" block encoding. used for eth protocol, etc. 144 type extblock struct { 145 Header *Header 146 Txs []*Transaction 147 Uncles []*Header 148 } 149 150 // "storage" block encoding. used for database. 151 type storageblock struct { 152 Header *Header 153 Txs []*Transaction 154 Uncles []*Header 155 TD *big.Int 156 } 157 158 var ( 159 emptyRootHash = DeriveSha(Transactions{}) 160 emptyUncleHash = CalcUncleHash(nil) 161 ) 162 163 // NewBlock creates a new block. The input data is copied, 164 // changes to header and to the field values will not affect the 165 // block. 166 // 167 // The values of TxHash, UncleHash, ReceiptHash and Bloom in header 168 // are ignored and set to values derived from the given txs, uncles 169 // and receipts. 170 func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block { 171 b := &Block{header: copyHeader(header), Td: new(big.Int)} 172 173 // TODO: panic if len(txs) != len(receipts) 174 if len(txs) == 0 { 175 b.header.TxHash = emptyRootHash 176 } else { 177 b.header.TxHash = DeriveSha(Transactions(txs)) 178 b.transactions = make(Transactions, len(txs)) 179 copy(b.transactions, txs) 180 } 181 182 if len(receipts) == 0 { 183 b.header.ReceiptHash = emptyRootHash 184 } else { 185 b.header.ReceiptHash = DeriveSha(Receipts(receipts)) 186 b.header.Bloom = CreateBloom(receipts) 187 b.receipts = make([]*Receipt, len(receipts)) 188 copy(b.receipts, receipts) 189 } 190 191 if len(uncles) == 0 { 192 b.header.UncleHash = emptyUncleHash 193 } else { 194 b.header.UncleHash = CalcUncleHash(uncles) 195 b.uncles = make([]*Header, len(uncles)) 196 for i := range uncles { 197 b.uncles[i] = copyHeader(uncles[i]) 198 } 199 } 200 201 return b 202 } 203 204 // NewBlockWithHeader creates a block with the given header data. The 205 // header data is copied, changes to header and to the field values 206 // will not affect the block. 207 func NewBlockWithHeader(header *Header) *Block { 208 return &Block{header: copyHeader(header)} 209 } 210 211 func copyHeader(h *Header) *Header { 212 cpy := *h 213 if cpy.Time = new(big.Int); h.Time != nil { 214 cpy.Time.Set(h.Time) 215 } 216 if cpy.Difficulty = new(big.Int); h.Difficulty != nil { 217 cpy.Difficulty.Set(h.Difficulty) 218 } 219 if cpy.Number = new(big.Int); h.Number != nil { 220 cpy.Number.Set(h.Number) 221 } 222 if cpy.GasLimit = new(big.Int); h.GasLimit != nil { 223 cpy.GasLimit.Set(h.GasLimit) 224 } 225 if cpy.GasUsed = new(big.Int); h.GasUsed != nil { 226 cpy.GasUsed.Set(h.GasUsed) 227 } 228 if len(h.Extra) > 0 { 229 cpy.Extra = make([]byte, len(h.Extra)) 230 copy(cpy.Extra, h.Extra) 231 } 232 return &cpy 233 } 234 235 func (b *Block) ValidateFields() error { 236 if b.header == nil { 237 return fmt.Errorf("header is nil") 238 } 239 for i, transaction := range b.transactions { 240 if transaction == nil { 241 return fmt.Errorf("transaction %d is nil", i) 242 } 243 } 244 for i, uncle := range b.uncles { 245 if uncle == nil { 246 return fmt.Errorf("uncle %d is nil", i) 247 } 248 } 249 return nil 250 } 251 252 func (b *Block) DecodeRLP(s *rlp.Stream) error { 253 var eb extblock 254 _, size, _ := s.Kind() 255 if err := s.Decode(&eb); err != nil { 256 return err 257 } 258 b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs 259 b.size.Store(common.StorageSize(rlp.ListSize(size))) 260 return nil 261 } 262 263 func (b *Block) EncodeRLP(w io.Writer) error { 264 return rlp.Encode(w, extblock{ 265 Header: b.header, 266 Txs: b.transactions, 267 Uncles: b.uncles, 268 }) 269 } 270 271 func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error { 272 var sb storageblock 273 if err := s.Decode(&sb); err != nil { 274 return err 275 } 276 b.header, b.uncles, b.transactions, b.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD 277 return nil 278 } 279 280 func (b *StorageBlock) EncodeRLP(w io.Writer) error { 281 return rlp.Encode(w, storageblock{ 282 Header: b.header, 283 Txs: b.transactions, 284 Uncles: b.uncles, 285 TD: b.Td, 286 }) 287 } 288 289 // TODO: copies 290 func (b *Block) Uncles() []*Header { return b.uncles } 291 func (b *Block) Transactions() Transactions { return b.transactions } 292 func (b *Block) Receipts() Receipts { return b.receipts } 293 294 func (b *Block) Transaction(hash common.Hash) *Transaction { 295 for _, transaction := range b.transactions { 296 if transaction.Hash() == hash { 297 return transaction 298 } 299 } 300 return nil 301 } 302 303 func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) } 304 func (b *Block) GasLimit() *big.Int { return new(big.Int).Set(b.header.GasLimit) } 305 func (b *Block) GasUsed() *big.Int { return new(big.Int).Set(b.header.GasUsed) } 306 func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) } 307 func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) } 308 309 func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() } 310 func (b *Block) MixDigest() common.Hash { return b.header.MixDigest } 311 func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) } 312 func (b *Block) Bloom() Bloom { return b.header.Bloom } 313 func (b *Block) Coinbase() common.Address { return b.header.Coinbase } 314 func (b *Block) Root() common.Hash { return b.header.Root } 315 func (b *Block) ParentHash() common.Hash { return b.header.ParentHash } 316 func (b *Block) TxHash() common.Hash { return b.header.TxHash } 317 func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash } 318 func (b *Block) UncleHash() common.Hash { return b.header.UncleHash } 319 func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) } 320 321 func (b *Block) Header() *Header { return copyHeader(b.header) } 322 323 func (b *Block) HashNoNonce() common.Hash { 324 return b.header.HashNoNonce() 325 } 326 327 func (b *Block) Size() common.StorageSize { 328 if size := b.size.Load(); size != nil { 329 return size.(common.StorageSize) 330 } 331 c := writeCounter(0) 332 rlp.Encode(&c, b) 333 b.size.Store(common.StorageSize(c)) 334 return common.StorageSize(c) 335 } 336 337 type writeCounter common.StorageSize 338 339 func (c *writeCounter) Write(b []byte) (int, error) { 340 *c += writeCounter(len(b)) 341 return len(b), nil 342 } 343 344 func CalcUncleHash(uncles []*Header) common.Hash { 345 return rlpHash(uncles) 346 } 347 348 // WithMiningResult returns a new block with the data from b 349 // where nonce and mix digest are set to the provided values. 350 func (b *Block) WithMiningResult(nonce uint64, mixDigest common.Hash) *Block { 351 cpy := *b.header 352 binary.BigEndian.PutUint64(cpy.Nonce[:], nonce) 353 cpy.MixDigest = mixDigest 354 return &Block{ 355 header: &cpy, 356 transactions: b.transactions, 357 receipts: b.receipts, 358 uncles: b.uncles, 359 Td: b.Td, 360 } 361 } 362 363 // Implement pow.Block 364 365 func (b *Block) Hash() common.Hash { 366 if hash := b.hash.Load(); hash != nil { 367 return hash.(common.Hash) 368 } 369 v := rlpHash(b.header) 370 b.hash.Store(v) 371 return v 372 } 373 374 func (b *Block) String() string { 375 str := fmt.Sprintf(`Block(#%v): Size: %v TD: %v { 376 MinerHash: %x 377 %v 378 Transactions: 379 %v 380 Uncles: 381 %v 382 } 383 `, b.Number(), b.Size(), b.Td, b.header.HashNoNonce(), b.header, b.transactions, b.uncles) 384 return str 385 } 386 387 func (h *Header) String() string { 388 return fmt.Sprintf(`Header(%x): 389 [ 390 ParentHash: %x 391 UncleHash: %x 392 Coinbase: %x 393 Root: %x 394 TxSha %x 395 ReceiptSha: %x 396 Bloom: %x 397 Difficulty: %v 398 Number: %v 399 GasLimit: %v 400 GasUsed: %v 401 Time: %v 402 Extra: %s 403 MixDigest: %x 404 Nonce: %x 405 ]`, h.Hash(), h.ParentHash, h.UncleHash, h.Coinbase, h.Root, h.TxHash, h.ReceiptHash, h.Bloom, h.Difficulty, h.Number, h.GasLimit, h.GasUsed, h.Time, h.Extra, h.MixDigest, h.Nonce) 406 } 407 408 type Blocks []*Block 409 410 type BlockBy func(b1, b2 *Block) bool 411 412 func (self BlockBy) Sort(blocks Blocks) { 413 bs := blockSorter{ 414 blocks: blocks, 415 by: self, 416 } 417 sort.Sort(bs) 418 } 419 420 type blockSorter struct { 421 blocks Blocks 422 by func(b1, b2 *Block) bool 423 } 424 425 func (self blockSorter) Len() int { return len(self.blocks) } 426 func (self blockSorter) Swap(i, j int) { 427 self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i] 428 } 429 func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) } 430 431 func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 }