From e3c79234e6ffccf1c4310b8b04167e83dae617a8 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 26 Apr 2017 18:51:45 -0600 Subject: [PATCH] gcs/builder: Add pre-BIP block filter and header calculations. --- gcs/builder/builder.go | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/gcs/builder/builder.go b/gcs/builder/builder.go index 45f0be8..7a2e5e0 100644 --- a/gcs/builder/builder.go +++ b/gcs/builder/builder.go @@ -271,3 +271,63 @@ func WithRandomKeyP(p uint8) *GCSBuilder { func WithRandomKey() *GCSBuilder { return WithRandomKeyPN(DefaultP, 0) } + +// BuildBasicFilter builds a basic GCS filter from a block. +func BuildBasicFilter(block *wire.MsgBlock) (*gcs.Filter, error) { + blockHash := block.BlockHash() + b := WithKeyHash(&blockHash) + _, err := b.Key() + if err != nil { + return nil, err + } + for i, tx := range block.Transactions { + // Skip the inputs for the coinbase transaction + if i != 0 { + for _, txIn := range tx.TxIn { + b.AddOutPoint(txIn.PreviousOutPoint) + } + } + for _, txOut := range tx.TxOut { + b.AddScript(txOut.PkScript) + } + } + return b.Build() +} + +// BuildExtFilter builds an extended GCS filter from a block. +func BuildExtFilter(block *wire.MsgBlock) (*gcs.Filter, error) { + blockHash := block.BlockHash() + b := WithKeyHash(&blockHash) + _, err := b.Key() + if err != nil { + return nil, err + } + for i, tx := range block.Transactions { + txHash := tx.TxHash() + b.AddHash(&txHash) + // Skip the inputs for the coinbase transaction + if i != 0 { + for _, txIn := range tx.TxIn { + b.AddScript(txIn.SignatureScript) + } + } + } + return b.Build() +} + +// GetFilterHash returns the double-SHA256 of the filter. +func GetFilterHash(filter *gcs.Filter) chainhash.Hash { + hash1 := chainhash.HashH(filter.NBytes()) + return chainhash.HashH(hash1[:]) +} + +// MakeHeaderForFilter makes a filter chain header for a filter, given the +// filter and the previous filter chain header. +func MakeHeaderForFilter(filter *gcs.Filter, prevHeader chainhash.Hash) chainhash.Hash { + filterTip := make([]byte, 2*chainhash.HashSize) + filterHash := GetFilterHash(filter) + copy(filterTip, filterHash[:]) + copy(filterTip[chainhash.HashSize:], prevHeader[:]) + hash1 := chainhash.HashH(filterTip) + return chainhash.HashH(hash1[:]) +}