|
|
@@ -15,71 +15,59 @@ import (
|
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
|
)
|
|
|
|
|
|
-type Header struct {
|
|
|
- // Hash to the previous block
|
|
|
- ParentHash common.Hash
|
|
|
- // Uncles of this block
|
|
|
- UncleHash common.Hash
|
|
|
- // The coin base address
|
|
|
- Coinbase common.Address
|
|
|
- // Block Trie state
|
|
|
- Root common.Hash
|
|
|
- // Tx sha
|
|
|
- TxHash common.Hash
|
|
|
- // Receipt sha
|
|
|
- ReceiptHash common.Hash
|
|
|
- // Bloom
|
|
|
- Bloom Bloom
|
|
|
- // Difficulty for the current block
|
|
|
- Difficulty *big.Int
|
|
|
- // The block number
|
|
|
- Number *big.Int
|
|
|
- // Gas limit
|
|
|
- GasLimit *big.Int
|
|
|
- // Gas used
|
|
|
- GasUsed *big.Int
|
|
|
- // Creation time
|
|
|
- Time uint64
|
|
|
- // Extra data
|
|
|
- Extra []byte
|
|
|
- // Mix digest for quick checking to prevent DOS
|
|
|
- MixDigest common.Hash
|
|
|
- // Nonce
|
|
|
- Nonce [8]byte
|
|
|
-}
|
|
|
+// A BlockNonce is a 64-bit hash which proves (combined with the
|
|
|
+// mix-hash) that a suffcient amount of computation has been carried
|
|
|
+// out on a block.
|
|
|
+type BlockNonce [8]byte
|
|
|
|
|
|
-func (self *Header) Hash() common.Hash {
|
|
|
- return rlpHash(self.rlpData(true))
|
|
|
+func EncodeNonce(i uint64) BlockNonce {
|
|
|
+ var n BlockNonce
|
|
|
+ binary.BigEndian.PutUint64(n[:], i)
|
|
|
+ return n
|
|
|
}
|
|
|
|
|
|
-func (self *Header) HashNoNonce() common.Hash {
|
|
|
- return rlpHash(self.rlpData(false))
|
|
|
+func (n BlockNonce) Uint64() uint64 {
|
|
|
+ return binary.BigEndian.Uint64(n[:])
|
|
|
}
|
|
|
|
|
|
-func (self *Header) rlpData(withNonce bool) []interface{} {
|
|
|
- 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,
|
|
|
- self.Extra,
|
|
|
- }
|
|
|
- if withNonce {
|
|
|
- fields = append(fields, self.MixDigest, self.Nonce)
|
|
|
- }
|
|
|
- return fields
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Header) RlpData() interface{} {
|
|
|
- return self.rlpData(true)
|
|
|
+type Header struct {
|
|
|
+ ParentHash common.Hash // Hash to the previous block
|
|
|
+ UncleHash common.Hash // Uncles of this block
|
|
|
+ Coinbase common.Address // The coin base address
|
|
|
+ Root common.Hash // Block Trie state
|
|
|
+ TxHash common.Hash // Tx sha
|
|
|
+ ReceiptHash common.Hash // Receipt sha
|
|
|
+ Bloom Bloom // Bloom
|
|
|
+ Difficulty *big.Int // Difficulty for the current block
|
|
|
+ Number *big.Int // The block number
|
|
|
+ GasLimit *big.Int // Gas limit
|
|
|
+ GasUsed *big.Int // Gas used
|
|
|
+ Time uint64 // Creation time
|
|
|
+ Extra []byte // Extra data
|
|
|
+ MixDigest common.Hash // for quick difficulty verification
|
|
|
+ Nonce BlockNonce
|
|
|
+}
|
|
|
+
|
|
|
+func (h *Header) Hash() common.Hash {
|
|
|
+ return rlpHash(h)
|
|
|
+}
|
|
|
+
|
|
|
+func (h *Header) HashNoNonce() common.Hash {
|
|
|
+ return rlpHash([]interface{}{
|
|
|
+ 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,
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
func (h *Header) UnmarshalJSON(data []byte) error {
|
|
|
@@ -112,20 +100,14 @@ func rlpHash(x interface{}) (h common.Hash) {
|
|
|
}
|
|
|
|
|
|
type Block struct {
|
|
|
- // Preset Hash for mock (Tests)
|
|
|
- HeaderHash common.Hash
|
|
|
- ParentHeaderHash common.Hash
|
|
|
- // ^^^^ ignore ^^^^
|
|
|
-
|
|
|
header *Header
|
|
|
uncles []*Header
|
|
|
transactions Transactions
|
|
|
- Td *big.Int
|
|
|
- queued bool // flag for blockpool to skip TD check
|
|
|
+ receipts Receipts
|
|
|
|
|
|
+ Td *big.Int
|
|
|
+ queued bool // flag for blockpool to skip TD check
|
|
|
ReceivedAt time.Time
|
|
|
-
|
|
|
- receipts Receipts
|
|
|
}
|
|
|
|
|
|
// StorageBlock defines the RLP encoding of a Block stored in the
|
|
|
@@ -148,43 +130,90 @@ type storageblock struct {
|
|
|
TD *big.Int
|
|
|
}
|
|
|
|
|
|
-func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash, difficulty *big.Int, nonce uint64, extra []byte) *Block {
|
|
|
- header := &Header{
|
|
|
- Root: root,
|
|
|
- ParentHash: parentHash,
|
|
|
- Coinbase: coinbase,
|
|
|
- Difficulty: difficulty,
|
|
|
- Time: uint64(time.Now().Unix()),
|
|
|
- Extra: extra,
|
|
|
- GasUsed: new(big.Int),
|
|
|
- GasLimit: new(big.Int),
|
|
|
- Number: new(big.Int),
|
|
|
+var (
|
|
|
+ emptyRootHash = DeriveSha(Transactions{})
|
|
|
+ emptyUncleHash = CalcUncleHash(nil)
|
|
|
+)
|
|
|
+
|
|
|
+// 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.
|
|
|
+func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block {
|
|
|
+ b := &Block{header: copyHeader(header), Td: new(big.Int)}
|
|
|
+
|
|
|
+ // TODO: panic if len(txs) != len(receipts)
|
|
|
+ if len(txs) == 0 {
|
|
|
+ b.header.TxHash = emptyRootHash
|
|
|
+ } else {
|
|
|
+ b.header.TxHash = DeriveSha(Transactions(txs))
|
|
|
+ b.transactions = make(Transactions, len(txs))
|
|
|
+ copy(b.transactions, txs)
|
|
|
}
|
|
|
- header.SetNonce(nonce)
|
|
|
- block := &Block{header: header}
|
|
|
- block.Td = new(big.Int)
|
|
|
|
|
|
- return block
|
|
|
-}
|
|
|
+ if len(receipts) == 0 {
|
|
|
+ b.header.ReceiptHash = emptyRootHash
|
|
|
+ } else {
|
|
|
+ b.header.ReceiptHash = DeriveSha(Receipts(receipts))
|
|
|
+ b.header.Bloom = CreateBloom(receipts)
|
|
|
+ b.receipts = make([]*Receipt, len(receipts))
|
|
|
+ copy(b.receipts, receipts)
|
|
|
+ }
|
|
|
|
|
|
-func (self *Header) SetNonce(nonce uint64) {
|
|
|
- binary.BigEndian.PutUint64(self.Nonce[:], nonce)
|
|
|
+ if len(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.
|
|
|
func NewBlockWithHeader(header *Header) *Block {
|
|
|
- return &Block{header: header}
|
|
|
+ return &Block{header: copyHeader(header)}
|
|
|
+}
|
|
|
+
|
|
|
+func copyHeader(h *Header) *Header {
|
|
|
+ cpy := *h
|
|
|
+ if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
|
|
|
+ cpy.Difficulty.Set(h.Difficulty)
|
|
|
+ }
|
|
|
+ if cpy.Number = new(big.Int); h.Number != nil {
|
|
|
+ cpy.Number.Set(h.Number)
|
|
|
+ }
|
|
|
+ if cpy.GasLimit = new(big.Int); h.GasLimit != nil {
|
|
|
+ cpy.GasLimit.Set(h.GasLimit)
|
|
|
+ }
|
|
|
+ if cpy.GasUsed = new(big.Int); h.GasUsed != nil {
|
|
|
+ cpy.GasUsed.Set(h.GasUsed)
|
|
|
+ }
|
|
|
+ if len(h.Extra) > 0 {
|
|
|
+ cpy.Extra = make([]byte, len(h.Extra))
|
|
|
+ copy(cpy.Extra, h.Extra)
|
|
|
+ }
|
|
|
+ return &cpy
|
|
|
}
|
|
|
|
|
|
-func (self *Block) ValidateFields() error {
|
|
|
- if self.header == nil {
|
|
|
+func (b *Block) ValidateFields() error {
|
|
|
+ if b.header == nil {
|
|
|
return fmt.Errorf("header is nil")
|
|
|
}
|
|
|
- for i, transaction := range self.transactions {
|
|
|
+ for i, transaction := range b.transactions {
|
|
|
if transaction == nil {
|
|
|
return fmt.Errorf("transaction %d is nil", i)
|
|
|
}
|
|
|
}
|
|
|
- for i, uncle := range self.uncles {
|
|
|
+ for i, uncle := range b.uncles {
|
|
|
if uncle == nil {
|
|
|
return fmt.Errorf("uncle %d is nil", i)
|
|
|
}
|
|
|
@@ -192,64 +221,48 @@ func (self *Block) ValidateFields() error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (self *Block) DecodeRLP(s *rlp.Stream) error {
|
|
|
+func (b *Block) DecodeRLP(s *rlp.Stream) error {
|
|
|
var eb extblock
|
|
|
if err := s.Decode(&eb); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- self.header, self.uncles, self.transactions = eb.Header, eb.Uncles, eb.Txs
|
|
|
+ b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (self Block) EncodeRLP(w io.Writer) error {
|
|
|
+func (b Block) EncodeRLP(w io.Writer) error {
|
|
|
return rlp.Encode(w, extblock{
|
|
|
- Header: self.header,
|
|
|
- Txs: self.transactions,
|
|
|
- Uncles: self.uncles,
|
|
|
+ Header: b.header,
|
|
|
+ Txs: b.transactions,
|
|
|
+ Uncles: b.uncles,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-func (self *StorageBlock) DecodeRLP(s *rlp.Stream) error {
|
|
|
+func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error {
|
|
|
var sb storageblock
|
|
|
if err := s.Decode(&sb); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- self.header, self.uncles, self.transactions, self.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
|
|
|
+ b.header, b.uncles, b.transactions, b.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (self StorageBlock) EncodeRLP(w io.Writer) error {
|
|
|
+func (b StorageBlock) EncodeRLP(w io.Writer) error {
|
|
|
return rlp.Encode(w, storageblock{
|
|
|
- Header: self.header,
|
|
|
- Txs: self.transactions,
|
|
|
- Uncles: self.uncles,
|
|
|
- TD: self.Td,
|
|
|
+ Header: b.header,
|
|
|
+ Txs: b.transactions,
|
|
|
+ Uncles: b.uncles,
|
|
|
+ TD: b.Td,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-func (self *Block) Header() *Header {
|
|
|
- return self.header
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Block) Uncles() []*Header {
|
|
|
- return self.uncles
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Block) CalculateUnclesHash() common.Hash {
|
|
|
- return rlpHash(self.uncles)
|
|
|
-}
|
|
|
+// TODO: copies
|
|
|
+func (b *Block) Uncles() []*Header { return b.uncles }
|
|
|
+func (b *Block) Transactions() Transactions { return b.transactions }
|
|
|
+func (b *Block) Receipts() Receipts { return b.receipts }
|
|
|
|
|
|
-func (self *Block) SetUncles(uncleHeaders []*Header) {
|
|
|
- self.uncles = uncleHeaders
|
|
|
- self.header.UncleHash = rlpHash(uncleHeaders)
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Block) Transactions() Transactions {
|
|
|
- return self.transactions
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Block) Transaction(hash common.Hash) *Transaction {
|
|
|
- for _, transaction := range self.transactions {
|
|
|
+func (b *Block) Transaction(hash common.Hash) *Transaction {
|
|
|
+ for _, transaction := range b.transactions {
|
|
|
if transaction.Hash() == hash {
|
|
|
return transaction
|
|
|
}
|
|
|
@@ -257,74 +270,33 @@ func (self *Block) Transaction(hash common.Hash) *Transaction {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (self *Block) SetTransactions(transactions Transactions) {
|
|
|
- self.transactions = transactions
|
|
|
- self.header.TxHash = DeriveSha(transactions)
|
|
|
-}
|
|
|
-func (self *Block) AddTransaction(transaction *Transaction) {
|
|
|
- self.transactions = append(self.transactions, transaction)
|
|
|
- self.SetTransactions(self.transactions)
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Block) Receipts() Receipts {
|
|
|
- return self.receipts
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Block) SetReceipts(receipts Receipts) {
|
|
|
- self.receipts = receipts
|
|
|
- self.header.ReceiptHash = DeriveSha(receipts)
|
|
|
- self.header.Bloom = CreateBloom(receipts)
|
|
|
-}
|
|
|
-func (self *Block) AddReceipt(receipt *Receipt) {
|
|
|
- self.receipts = append(self.receipts, receipt)
|
|
|
- self.SetReceipts(self.receipts)
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Block) RlpData() interface{} {
|
|
|
- return []interface{}{self.header, self.transactions, self.uncles}
|
|
|
-}
|
|
|
+func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) }
|
|
|
+func (b *Block) GasLimit() *big.Int { return new(big.Int).Set(b.header.GasLimit) }
|
|
|
+func (b *Block) GasUsed() *big.Int { return new(big.Int).Set(b.header.GasUsed) }
|
|
|
+func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
|
|
|
|
|
|
-func (self *Block) RlpDataForStorage() interface{} {
|
|
|
- return []interface{}{self.header, self.transactions, self.uncles, self.Td /* TODO receipts */}
|
|
|
-}
|
|
|
+func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() }
|
|
|
+func (b *Block) MixDigest() common.Hash { return b.header.MixDigest }
|
|
|
+func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
|
|
|
+func (b *Block) Bloom() Bloom { return b.header.Bloom }
|
|
|
+func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
|
|
|
+func (b *Block) Time() int64 { return int64(b.header.Time) }
|
|
|
+func (b *Block) Root() common.Hash { return b.header.Root }
|
|
|
+func (b *Block) ParentHash() common.Hash { return b.header.ParentHash }
|
|
|
+func (b *Block) TxHash() common.Hash { return b.header.TxHash }
|
|
|
+func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
|
|
|
+func (b *Block) UncleHash() common.Hash { return b.header.UncleHash }
|
|
|
+func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) }
|
|
|
|
|
|
-// Header accessors (add as you need them)
|
|
|
-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 }
|
|
|
-func (self *Block) Nonce() uint64 {
|
|
|
- return binary.BigEndian.Uint64(self.header.Nonce[:])
|
|
|
-}
|
|
|
-func (self *Block) SetNonce(nonce uint64) {
|
|
|
- self.header.SetNonce(nonce)
|
|
|
-}
|
|
|
+func (b *Block) Header() *Header { return copyHeader(b.header) }
|
|
|
|
|
|
-func (self *Block) Queued() bool { return self.queued }
|
|
|
-func (self *Block) SetQueued(q bool) { self.queued = q }
|
|
|
-
|
|
|
-func (self *Block) Bloom() Bloom { return self.header.Bloom }
|
|
|
-func (self *Block) Coinbase() common.Address { return self.header.Coinbase }
|
|
|
-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 }
|
|
|
-func (self *Block) Root() common.Hash { return self.header.Root }
|
|
|
-func (self *Block) SetRoot(root common.Hash) { self.header.Root = root }
|
|
|
-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
|
|
|
+func (b *Block) HashNoNonce() common.Hash {
|
|
|
+ return b.header.HashNoNonce()
|
|
|
}
|
|
|
|
|
|
-func (self *Block) Size() common.StorageSize {
|
|
|
+func (b *Block) Size() common.StorageSize {
|
|
|
c := writeCounter(0)
|
|
|
- rlp.Encode(&c, self)
|
|
|
+ rlp.Encode(&c, b)
|
|
|
return common.StorageSize(c)
|
|
|
}
|
|
|
|
|
|
@@ -335,48 +307,32 @@ func (c *writeCounter) Write(b []byte) (int, error) {
|
|
|
return len(b), nil
|
|
|
}
|
|
|
|
|
|
-// Implement pow.Block
|
|
|
-func (self *Block) Difficulty() *big.Int { return self.header.Difficulty }
|
|
|
-func (self *Block) HashNoNonce() common.Hash { return self.header.HashNoNonce() }
|
|
|
-
|
|
|
-func (self *Block) Hash() common.Hash {
|
|
|
- if (self.HeaderHash != common.Hash{}) {
|
|
|
- return self.HeaderHash
|
|
|
- } else {
|
|
|
- return self.header.Hash()
|
|
|
- }
|
|
|
+func CalcUncleHash(uncles []*Header) common.Hash {
|
|
|
+ return rlpHash(uncles)
|
|
|
}
|
|
|
|
|
|
-func (self *Block) ParentHash() common.Hash {
|
|
|
- if (self.ParentHeaderHash != common.Hash{}) {
|
|
|
- return self.ParentHeaderHash
|
|
|
- } else {
|
|
|
- return self.header.ParentHash
|
|
|
+// WithMiningResult returns a new block with the data from b
|
|
|
+// where nonce and mix digest are set to the provided values.
|
|
|
+func (b *Block) WithMiningResult(nonce uint64, mixDigest common.Hash) *Block {
|
|
|
+ cpy := *b.header
|
|
|
+ binary.BigEndian.PutUint64(cpy.Nonce[:], nonce)
|
|
|
+ cpy.MixDigest = mixDigest
|
|
|
+ return &Block{
|
|
|
+ header: &cpy,
|
|
|
+ transactions: b.transactions,
|
|
|
+ receipts: b.receipts,
|
|
|
+ uncles: b.uncles,
|
|
|
+ Td: b.Td,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (self *Block) Copy() *Block {
|
|
|
- block := NewBlock(self.header.ParentHash, self.Coinbase(), self.Root(), new(big.Int), self.Nonce(), self.header.Extra)
|
|
|
- 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)
|
|
|
- block.header.Number.Set(self.header.Number)
|
|
|
- block.header.Time = self.header.Time
|
|
|
- block.header.MixDigest = self.header.MixDigest
|
|
|
- if self.Td != nil {
|
|
|
- block.Td.Set(self.Td)
|
|
|
- }
|
|
|
+// Implement pow.Block
|
|
|
|
|
|
- return block
|
|
|
+func (b *Block) Hash() common.Hash {
|
|
|
+ return b.header.Hash()
|
|
|
}
|
|
|
|
|
|
-func (self *Block) String() string {
|
|
|
+func (b *Block) String() string {
|
|
|
str := fmt.Sprintf(`Block(#%v): Size: %v TD: %v {
|
|
|
MinerHash: %x
|
|
|
%v
|
|
|
@@ -385,20 +341,11 @@ Transactions:
|
|
|
Uncles:
|
|
|
%v
|
|
|
}
|
|
|
-`, self.Number(), self.Size(), self.Td, self.header.HashNoNonce(), self.header, self.transactions, self.uncles)
|
|
|
-
|
|
|
- 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)
|
|
|
- }
|
|
|
-
|
|
|
+`, b.Number(), b.Size(), b.Td, b.header.HashNoNonce(), b.header, b.transactions, b.uncles)
|
|
|
return str
|
|
|
}
|
|
|
|
|
|
-func (self *Header) String() string {
|
|
|
+func (h *Header) String() string {
|
|
|
return fmt.Sprintf(`Header(%x):
|
|
|
[
|
|
|
ParentHash: %x
|
|
|
@@ -414,9 +361,9 @@ func (self *Header) String() string {
|
|
|
GasUsed: %v
|
|
|
Time: %v
|
|
|
Extra: %s
|
|
|
- MixDigest: %x
|
|
|
+ MixDigest: %x
|
|
|
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)
|
|
|
+]`, 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)
|
|
|
}
|
|
|
|
|
|
type Blocks []*Block
|
|
|
@@ -442,4 +389,4 @@ func (self blockSorter) Swap(i, j int) {
|
|
|
}
|
|
|
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.Header().Number.Cmp(b2.Header().Number) < 0 }
|
|
|
+func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 }
|