Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Pollard hashes up to populated nodes, not all the way to roots #226

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
03a1fb9
slim down tests
adiabat Nov 14, 2020
8b90d15
replace [3]node with miniTree
adiabat Nov 14, 2020
9b9db11
make verifyBatchProof() a method on Pollard
adiabat Nov 14, 2020
9861d9f
have verifyBatchProof() do it's own reading from the pollard,
adiabat Nov 14, 2020
0e278da
slight changes to formatting and comments
adiabat Nov 14, 2020
3db1d2f
change datadir path (specifies blocks, not bitcoin dir)
adiabat Dec 18, 2020
bb24cfd
remove some unused functions; revert proofs to still include target h…
adiabat Dec 20, 2020
0835f18
structure of compact serialization / deserialization for ublocks
adiabat Dec 21, 2020
e0261ea
add functions for recovering leaf data from block data
adiabat Dec 21, 2020
d2b99ee
compact deserialization needs skiplists, so pass those along
adiabat Dec 22, 2020
af86dc0
obvious fix in UData SerializeCompactSize()
adiabat Dec 22, 2020
f24feb2
compact serialization doesn't crash; but reconstruct wants target hashes
adiabat Dec 22, 2020
611dfee
remove computablePositions from ProofPositions() functions
adiabat Jan 2, 2021
05f9171
compiles / fits but proof hashes don't match up
adiabat Jan 2, 2021
1ffe55a
remove stateless reconstruct / verify of block proofs
adiabat Jan 2, 2021
0fa6964
remove redundant functions from pollard
adiabat Jan 3, 2021
9678cf6
get rid of pollard full
adiabat Jan 3, 2021
72fe405
add comments about changes to IngestBatchProof()
adiabat Jan 4, 2021
8bb472d
add better printfs for debugging
adiabat Jan 29, 2021
248d86b
make tests compile (they don't pass)
adiabat Jan 29, 2021
4739809
aha the test is now wrong
adiabat Jan 29, 2021
939f692
start rewrite of ingest
adiabat Jan 30, 2021
337c75a
building ingestAndCheck but need to change grabPos
adiabat Jan 30, 2021
a015047
revert grabPos, new function to build 2d slice like ProofPositions bu…
adiabat Jan 30, 2021
2e152f4
add notes
adiabat Feb 1, 2021
86c7ad0
more notes on ways to change blockproofs
adiabat Apr 16, 2021
a4b40e6
add proofPositions2
adiabat Apr 17, 2021
4f64761
add notes about hashing to known
adiabat Apr 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions util/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ func (l *LeafData) DeserializeCompact(r io.Reader) (flag byte, err error) {
return
}
if flag == LeafFlagP2PKH {
// if it's P2PKH the flag alone is enough; no PKH data is given
return
}

Expand Down Expand Up @@ -525,6 +526,7 @@ func (ub *UBlock) SerializeCompactSize() int {
// rebuilt from the block data. Note that this leaves the blockhash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The blockhash is not yet being restored right? at least i can't find it in any of the commits.
This also assumes a height to blockhash index on the client side exists, might not be worth it if the saving aren't huge.

// empty in the leaf data, so that needs to be filled in by lookup up
// the headers (block height is provided)
// The 2 things to rebuild here are outpoint and pkscript
func (ub *UBlock) DeserializeCompact(r io.Reader) (err error) {
err = ub.Block.Deserialize(r)
if err != nil {
Expand All @@ -540,16 +542,46 @@ func (ub *UBlock) DeserializeCompact(r io.Reader) (err error) {
len(flags), len(ub.UtreexoData.Stxos))
return
}
// make sure the number of targets in the proof side matches the
// number of inputs in the block
proofsRemaining := len(flags)
for i, tx := range ub.Block.Transactions {
if i == 0 {
continue
}
proofsRemaining -= len(tx.TxIn)
}
// if it doesn't match, fail
if proofsRemaining != 0 {
err = fmt.Errorf("%d txos proven but %d inputs in block",
len(flags), len(flags)-proofsRemaining)
return
}
// we know the leaf data & inputs match up, at least in number, so
// rebuild the leaf data. It could be wrong but we'll find out later
// if the hashes / proofs don't match.
txinInBlock := 0
for i, tx := range ub.Block.Transactions {
if i == 0 {
continue // skip coinbase
}
for _, in := range tx.TxIn {
// rebuild leaf data from this txin data (OP and PkScript)
// copy outpoint from block into leaf
ub.UtreexoData.Stxos[txinInBlock].Outpoint = in.PreviousOutPoint
// rebuild pkscript based on flag

// so far only P2PKH are omitted / recovered
if flags[txinInBlock] == LeafFlagP2PKH {
// get pubkey from sigscript
ub.UtreexoData.Stxos[txinInBlock].PkScript, err =
RecoverPkScriptP2PKH(in.SignatureScript)
if err != nil {
return
}
}
txinInBlock++
}
}

return
Expand Down
30 changes: 30 additions & 0 deletions util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"sort"
"time"

"github.com/btcsuite/btcutil"

"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/mit-dci/utreexo/accumulator"
Expand Down Expand Up @@ -313,3 +315,31 @@ func IsP2PKH(pks []byte) bool {
pks[0] == 0x76 && pks[1] == 0xa9 && pks[2] == 0x14 &&
pks[23] == 0x88 && pks[24] == 0xac
}

// given a P2PKH scriptSig, output the original scriptPubKey
func RecoverPkScriptP2PKH(scriptSig []byte) ([]byte, error) {
if len(scriptSig) == 0 {
return nil, fmt.Errorf("RecoverPkScriptP2PKH give empty scriptSig")
}
siglen := scriptSig[0]
if len(scriptSig)+1 < int(siglen) {
return nil, fmt.Errorf("RecoverPkScriptP2PKH can't pop signature")
}
scriptSig = scriptSig[siglen+1:]
pklen := scriptSig[0]
if len(scriptSig)+1 < int(pklen) {
return nil, fmt.Errorf("RecoverPkScriptP2PKH can't pop pubkey")
}
pkh := btcutil.Hash160(scriptSig[1 : 1+pklen])
return p2pkhify(pkh), nil
}

// turns a pubkey hash into a normal bitcoin p2pkh spend script.
// no checks on the input. if it's not 20 bytes, will return a script
// that won't work.
func p2pkhify(pkh []byte) (script []byte) {
script = []byte{0x76, 0xa9, 0x14}
script = append(script, pkh...)
script = append(script, []byte{0x88, 0xac}...)
return
}