Skip to content

Commit

Permalink
types,gateway: Refactor BlockHeader
Browse files Browse the repository at this point in the history
  • Loading branch information
lukechampine committed Nov 19, 2024
1 parent b8408d6 commit ecd2939
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 103 deletions.
10 changes: 5 additions & 5 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ type MidState struct {
}

func (ms *MidState) siacoinElement(ts V1TransactionSupplement, id types.SiacoinOutputID) (types.SiacoinElement, bool) {
if i, ok := ms.created[types.Hash256(id)]; ok {
if i, ok := ms.created[id]; ok {
return ms.sces[i], true
}
return ts.siacoinElement(id)
Expand Down Expand Up @@ -714,7 +714,7 @@ func (ts *V1TransactionSupplement) DecodeFrom(d *types.Decoder) {

func (ts V1TransactionSupplement) siacoinElement(id types.SiacoinOutputID) (sce types.SiacoinElement, ok bool) {
for _, sce := range ts.SiacoinInputs {
if types.SiacoinOutputID(sce.ID) == id {
if sce.ID == id {
return sce, true
}
}
Expand All @@ -723,7 +723,7 @@ func (ts V1TransactionSupplement) siacoinElement(id types.SiacoinOutputID) (sce

func (ts V1TransactionSupplement) siafundElement(id types.SiafundOutputID) (sfe types.SiafundElement, ok bool) {
for _, sfe := range ts.SiafundInputs {
if types.SiafundOutputID(sfe.ID) == id {
if sfe.ID == id {
return sfe, true
}
}
Expand All @@ -732,7 +732,7 @@ func (ts V1TransactionSupplement) siafundElement(id types.SiafundOutputID) (sfe

func (ts V1TransactionSupplement) revision(id types.FileContractID) (fce types.FileContractElement, ok bool) {
for _, fce := range ts.RevisedFileContracts {
if types.FileContractID(fce.ID) == id {
if fce.ID == id {
return fce, true
}
}
Expand All @@ -741,7 +741,7 @@ func (ts V1TransactionSupplement) revision(id types.FileContractID) (fce types.F

func (ts V1TransactionSupplement) storageProof(id types.FileContractID) (sps V1StorageProofSupplement, ok bool) {
for _, sps := range ts.StorageProofs {
if types.FileContractID(sps.FileContract.ID) == id {
if sps.FileContract.ID == id {
return sps, true
}
}
Expand Down
44 changes: 7 additions & 37 deletions gateway/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,36 +53,6 @@ func (h *Header) decodeFrom(d *types.Decoder) {
h.NetAddress = d.ReadString()
}

func (h *BlockHeader) encodeTo(e *types.Encoder) {
h.ParentID.EncodeTo(e)
e.WriteUint64(h.Nonce)
e.WriteTime(h.Timestamp)
h.MerkleRoot.EncodeTo(e)
}

func (h *BlockHeader) decodeFrom(d *types.Decoder) {
h.ParentID.DecodeFrom(d)
h.Nonce = d.ReadUint64()
h.Timestamp = d.ReadTime()
h.MerkleRoot.DecodeFrom(d)
}

func (h *V2BlockHeader) encodeTo(e *types.Encoder) {
h.Parent.EncodeTo(e)
e.WriteUint64(h.Nonce)
e.WriteTime(h.Timestamp)
h.TransactionsRoot.EncodeTo(e)
h.MinerAddress.EncodeTo(e)
}

func (h *V2BlockHeader) decodeFrom(d *types.Decoder) {
h.Parent.DecodeFrom(d)
h.Nonce = d.ReadUint64()
h.Timestamp = d.ReadTime()
h.TransactionsRoot.DecodeFrom(d)
h.MinerAddress.DecodeFrom(d)
}

func (ob *V2BlockOutline) encodeTo(e *types.Encoder) {
e.WriteUint64(ob.Height)
ob.ParentID.EncodeTo(e)
Expand Down Expand Up @@ -261,12 +231,12 @@ func (r *RPCSendBlk) maxResponseLen() int { return 5e6 }

// RPCRelayHeader relays a header.
type RPCRelayHeader struct {
Header BlockHeader
Header types.BlockHeader
emptyResponse
}

func (r *RPCRelayHeader) encodeRequest(e *types.Encoder) { r.Header.encodeTo(e) }
func (r *RPCRelayHeader) decodeRequest(d *types.Decoder) { r.Header.decodeFrom(d) }
func (r *RPCRelayHeader) encodeRequest(e *types.Encoder) { r.Header.EncodeTo(e) }
func (r *RPCRelayHeader) decodeRequest(d *types.Decoder) { r.Header.DecodeFrom(d) }
func (r *RPCRelayHeader) maxRequestLen() int { return 32 + 8 + 8 + 32 }

// RPCRelayTransactionSet relays a transaction set.
Expand Down Expand Up @@ -364,13 +334,13 @@ func (r *RPCSendCheckpoint) maxResponseLen() int { return 5e6 + 4e3 }

// RPCRelayV2Header relays a v2 block header.
type RPCRelayV2Header struct {
Header V2BlockHeader
Header types.BlockHeader
emptyResponse
}

func (r *RPCRelayV2Header) encodeRequest(e *types.Encoder) { r.Header.encodeTo(e) }
func (r *RPCRelayV2Header) decodeRequest(d *types.Decoder) { r.Header.decodeFrom(d) }
func (r *RPCRelayV2Header) maxRequestLen() int { return 8 + 32 + 8 + 8 + 32 + 32 }
func (r *RPCRelayV2Header) encodeRequest(e *types.Encoder) { r.Header.EncodeTo(e) }
func (r *RPCRelayV2Header) decodeRequest(d *types.Decoder) { r.Header.DecodeFrom(d) }
func (r *RPCRelayV2Header) maxRequestLen() int { return 8 + 32 + 32 + 8 }

// RPCRelayV2BlockOutline relays a v2 block outline.
type RPCRelayV2BlockOutline struct {
Expand Down
48 changes: 6 additions & 42 deletions gateway/outline.go
Original file line number Diff line number Diff line change
@@ -1,50 +1,13 @@
package gateway

import (
"encoding/binary"
"time"

"go.sia.tech/core/consensus"
"go.sia.tech/core/internal/blake2b"
"go.sia.tech/core/types"
)

// A BlockHeader contains a Block's non-transaction data.
type BlockHeader struct {
ParentID types.BlockID
Nonce uint64
Timestamp time.Time
MerkleRoot types.Hash256
}

// ID returns a hash that uniquely identifies the block.
func (h BlockHeader) ID() types.BlockID {
buf := make([]byte, 32+8+8+32)
copy(buf[:32], h.ParentID[:])
binary.LittleEndian.PutUint64(buf[32:], h.Nonce)
binary.LittleEndian.PutUint64(buf[40:], uint64(h.Timestamp.Unix()))
copy(buf[48:], h.MerkleRoot[:])
return types.BlockID(types.HashBytes(buf))
}

// A V2BlockHeader contains a V2Block's non-transaction data.
type V2BlockHeader struct {
Parent types.ChainIndex
Nonce uint64
Timestamp time.Time
TransactionsRoot types.Hash256
MinerAddress types.Address
}

// ID returns a hash that uniquely identifies the block.
func (h V2BlockHeader) ID(cs consensus.State) types.BlockID {
return (&types.Block{
Nonce: h.Nonce,
Timestamp: h.Timestamp,
V2: &types.V2BlockData{Commitment: cs.Commitment(h.TransactionsRoot, h.MinerAddress)},
}).ID()
}

// An OutlineTransaction identifies a transaction by its full hash. The actual
// transaction data may or may not be present.
type OutlineTransaction struct {
Expand Down Expand Up @@ -75,11 +38,12 @@ func (bo V2BlockOutline) commitment(cs consensus.State) types.Hash256 {

// ID returns a hash that uniquely identifies the block.
func (bo V2BlockOutline) ID(cs consensus.State) types.BlockID {
return (&types.Block{
Nonce: bo.Nonce,
Timestamp: bo.Timestamp,
V2: &types.V2BlockData{Commitment: bo.commitment(cs)},
}).ID()
return types.BlockHeader{
ParentID: bo.ParentID,
Nonce: bo.Nonce,
Timestamp: bo.Timestamp,
Commitment: bo.commitment(cs),
}.ID()
}

// Missing returns the hashes of transactions that are missing from the block.
Expand Down
16 changes: 16 additions & 0 deletions types/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,14 @@ func (b V2BlockData) EncodeTo(e *Encoder) {
V2TransactionsMultiproof(b.Transactions).EncodeTo(e)
}

// EncodeTo implements types.EncoderTo.
func (h BlockHeader) EncodeTo(e *Encoder) {
h.ParentID.EncodeTo(e)
e.WriteUint64(h.Nonce)
e.WriteTime(h.Timestamp)
h.Commitment.EncodeTo(e)
}

// V1Block provides v1 encoding for Block.
type V1Block Block

Expand Down Expand Up @@ -1357,6 +1365,14 @@ func (b *V2BlockData) DecodeFrom(d *Decoder) {
(*V2TransactionsMultiproof)(&b.Transactions).DecodeFrom(d)
}

// DecodeFrom implements types.DecoderFrom.
func (h *BlockHeader) DecodeFrom(d *Decoder) {
h.ParentID.DecodeFrom(d)
h.Nonce = d.ReadUint64()
h.Timestamp = d.ReadTime()
h.Commitment.DecodeFrom(d)
}

// DecodeFrom implements types.DecoderFrom.
func (b *V1Block) DecodeFrom(d *Decoder) {
b.ParentID.DecodeFrom(d)
Expand Down
57 changes: 38 additions & 19 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,26 @@ type V2BlockData struct {
Transactions []V2Transaction `json:"transactions"`
}

// A Block is a set of transactions grouped under a header.
// A BlockHeader is the preimage of a Block's ID.
type BlockHeader struct {
ParentID BlockID `json:"parentID"`
Nonce uint64 `json:"nonce"`
Timestamp time.Time `json:"timestamp"`
Commitment Hash256 `json:"commitment"`
}

// ID returns the hash of the header data.
func (bh BlockHeader) ID() BlockID {
buf := make([]byte, 32+8+8+32)
copy(buf[:32], bh.ParentID[:])
binary.LittleEndian.PutUint64(buf[32:], bh.Nonce)
binary.LittleEndian.PutUint64(buf[40:], uint64(bh.Timestamp.Unix()))
copy(buf[48:], bh.Commitment[:])
return BlockID(HashBytes(buf))
}

// A Block is a timestamped set of transactions, immutably linked to a previous
// block, secured by proof-of-work.
type Block struct {
ParentID BlockID `json:"parentID"`
Nonce uint64 `json:"nonce"`
Expand All @@ -815,12 +834,6 @@ type Block struct {
V2 *V2BlockData `json:"v2,omitempty"`
}

// MerkleRoot returns the Merkle root of the block's miner payouts and
// transactions.
func (b *Block) MerkleRoot() Hash256 {
return blockMerkleRoot(b.MinerPayouts, b.Transactions)
}

// V2Transactions returns the block's v2 transactions, if present.
func (b *Block) V2Transactions() []V2Transaction {
if b.V2 != nil {
Expand All @@ -829,20 +842,26 @@ func (b *Block) V2Transactions() []V2Transaction {
return nil
}

// ID returns a hash that uniquely identifies a block.
func (b *Block) ID() BlockID {
buf := make([]byte, 32+8+8+32)
binary.LittleEndian.PutUint64(buf[32:], b.Nonce)
binary.LittleEndian.PutUint64(buf[40:], uint64(b.Timestamp.Unix()))
if b.V2 != nil {
copy(buf[:32], "sia/id/block|")
copy(buf[48:], b.V2.Commitment[:])
// Header returns the block's header.
func (b *Block) Header() BlockHeader {
var commitment Hash256
if b.V2 == nil {
// NOTE: expensive!
commitment = blockMerkleRoot(b.MinerPayouts, b.Transactions)
} else {
root := b.MerkleRoot() // NOTE: expensive!
copy(buf[:32], b.ParentID[:])
copy(buf[48:], root[:])
commitment = b.V2.Commitment
}
return BlockID(HashBytes(buf))
return BlockHeader{
ParentID: b.ParentID,
Nonce: b.Nonce,
Timestamp: b.Timestamp,
Commitment: commitment,
}
}

// ID returns a hash that uniquely identifies a block.
func (b *Block) ID() BlockID {
return b.Header().ID()
}

func unmarshalHex(dst []byte, data []byte) error {
Expand Down

0 comments on commit ecd2939

Please sign in to comment.