// A BlockNonce is a 64-bit hash which proves (combined with the // mix-hash) that a sufficient amount of computation has been carried // out on a block. type BlockNonce [8]byte
// Body is a simple (mutable, non-safe) data container for storing and moving // a block's data contents (transactions and uncles) together. type Body struct { Transactions []*Transaction Uncles []*Header }
// EncodeNonce converts the given integer to a block nonce. funcEncodeNonce(i uint64) BlockNonce { var n BlockNonce binary.BigEndian.PutUint64(n[:], i) return n }
//BlockNonce 转成整数
// Uint64 returns the integer value of a block nonce. func(n BlockNonce) Uint64() uint64 { return binary.BigEndian.Uint64(n[:]) }
//BlockNonce 转换成十六进制字节
// MarshalText encodes n as a hex string with 0x prefix. func(n BlockNonce) MarshalText() ([]byte, error) { return hexutil.Bytes(n[:]).MarshalText() }
//反射类型用于获取运行时信息,这里获取 header 的内存的字节数,和动态类型相关 var headerSize = common.StorageSize(reflect.TypeOf(Header{}).Size())
//获取区块头占用的内存大小,用于估计占用内存和限制内存消耗
// Size returns the approximate memory used by all internal contents. It is used // to approximate and limit the memory consumption of various caches. func(h *Header) Size() common.StorageSize { return headerSize + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen())/8) }
//检查字段是否合理以及动态类型所占用的内存是否合理
// SanityCheck checks a few basic things -- these checks are way beyond what // any 'sane' production values should hold, and can mainly be used to prevent // that the unbounded fields are stuffed with junk data to add processing // overhead func(h *Header) SanityCheck() error { if h.Number != nil && !h.Number.IsUint64() { return fmt.Errorf("too large block number: bitlen %d", h.Number.BitLen()) } if h.Difficulty != nil { if diffLen := h.Difficulty.BitLen(); diffLen > 80 { return fmt.Errorf("too large block difficulty: bitlen %d", diffLen) } } if eLen := len(h.Extra); eLen > 100*1024 { return fmt.Errorf("too large block extradata: size %d", eLen) } if h.BaseFee != nil { if bfLen := h.BaseFee.BitLen(); bfLen > 256 { return fmt.Errorf("too large base fee: bitlen %d", bfLen) } } returnnil }
// NewBlock creates a new block. The input data is copied, // changes to header and to the field values will not affect the // block. // // The values of TxHash, UncleHash, ReceiptHash and Bloom in header // are ignored and set to values derived from the given txs, uncles // and receipts. funcNewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, hasher TrieHasher) *Block { b := &Block{header: CopyHeader(header), td: new(big.Int)}
iflen(uncles) == 0 { b.header.UncleHash = EmptyUncleHash } else { b.header.UncleHash = CalcUncleHash(uncles) //生成叔块哈希 b.uncles = make([]*Header, len(uncles)) for i := range uncles { b.uncles[i] = CopyHeader(uncles[i]) } }
return b }
// NewBlockWithHeader creates a block with the given header data. The // header data is copied, changes to header and to the field values // will not affect the block. funcNewBlockWithHeader(header *Header) *Block { return &Block{header: CopyHeader(header)} }
// Body returns the non-header content of the block. func(b *Block) Body() *Body { return &Body{b.transactions, b.uncles} }
// Size returns the true RLP encoded storage size of the block, either by encoding // and returning it, or returning a previsouly cached value. func(b *Block) Size() common.StorageSize { if size := b.size.Load(); size != nil { return size.(common.StorageSize) } c := writeCounter(0) rlp.Encode(&c, b) b.size.Store(common.StorageSize(c)) return common.StorageSize(c) }
// WithSeal returns a new block with the data from b but the header replaced with // the sealed one. func(b *Block) WithSeal(header *Header) *Block { cpy := *header