summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.mediawiki8
-rw-r--r--bip-0011.mediawiki2
-rw-r--r--bip-0016.mediawiki2
-rw-r--r--bip-0042.mediawiki2
-rw-r--r--bip-0061.mediawiki2
-rw-r--r--bip-0098.mediawiki6
-rw-r--r--bip-0116.mediawiki4
-rw-r--r--bip-0117.mediawiki2
-rw-r--r--bip-0125.mediawiki2
-rw-r--r--bip-0143.mediawiki4
-rw-r--r--bip-0157.mediawiki2
-rw-r--r--bip-0158.mediawiki99
-rw-r--r--bip-0158/gentestvectors.go380
-rw-r--r--bip-0158/testnet-19.json (renamed from bip-0158/testnet-20.json)15
-rw-r--r--bip-0173.mediawiki2
15 files changed, 240 insertions, 292 deletions
diff --git a/README.mediawiki b/README.mediawiki
index b674772..a052fb4 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -223,13 +223,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Marek Palatinus
| Standard
| BIP number allocated
-|-
+|-style="background-color: #cfffcf"
| [[bip-0042.mediawiki|42]]
| Consensus (soft fork)
| A finite monetary supply for Bitcoin
| Pieter Wuille
| Standard
-| Draft
+| Final
|-
| [[bip-0043.mediawiki|43]]
| Applications
@@ -770,13 +770,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Luke Dashjr
| Standard
| Draft
-|- style="background-color: #ffffcf"
+|- style="background-color: #cfffcf"
| [[bip-0173.mediawiki|173]]
| Applications
| Base32 address format for native v0-16 witness outputs
| Pieter Wuille, Greg Maxwell
| Informational
-| Proposed
+| Final
|-
| [[bip-0174.mediawiki|174]]
| Applications
diff --git a/bip-0011.mediawiki b/bip-0011.mediawiki
index bb0a308..e5052eb 100644
--- a/bip-0011.mediawiki
+++ b/bip-0011.mediawiki
@@ -38,7 +38,7 @@ OP_CHECKMULTISIG transactions are redeemed using a standard scriptSig:
(OP_0 is required because of a bug in OP_CHECKMULTISIG; it pops one too many items off the execution stack, so a dummy value must be placed on the stack).
-The current Satoshi bitcoin client does not relay or mine transactions with scriptSigs larger than 200 bytes; to accomodate 3-signature transactions, this will be increased to 500 bytes.
+The current Satoshi bitcoin client does not relay or mine transactions with scriptSigs larger than 200 bytes; to accommodate 3-signature transactions, this will be increased to 500 bytes.
==Rationale==
diff --git a/bip-0016.mediawiki b/bip-0016.mediawiki
index d5d39ef..ba828e1 100644
--- a/bip-0016.mediawiki
+++ b/bip-0016.mediawiki
@@ -101,7 +101,7 @@ If a majority of hashing power does not support the new validation rules, then r
===520-byte limitation on serialized script size===
-As a consequence of the requirement for backwards compatiblity the serialized script is itself subject to the same rules as any other PUSHDATA operation, including the rule that no data greater than 520 bytes may be pushed to the stack. Thus it is not possible to spend a P2SH output if the redemption script it refers to is >520 bytes in length. For instance while the OP_CHECKMULTISIG opcode can itself accept up to 20 pubkeys, with 33-byte compressed pubkeys it is only possible to spend a P2SH output requiring a maximum of 15 pubkeys to redeem: 3 bytes + 15 pubkeys * 34 bytes/pubkey = 513 bytes.
+As a consequence of the requirement for backwards compatibility the serialized script is itself subject to the same rules as any other PUSHDATA operation, including the rule that no data greater than 520 bytes may be pushed to the stack. Thus it is not possible to spend a P2SH output if the redemption script it refers to is >520 bytes in length. For instance while the OP_CHECKMULTISIG opcode can itself accept up to 20 pubkeys, with 33-byte compressed pubkeys it is only possible to spend a P2SH output requiring a maximum of 15 pubkeys to redeem: 3 bytes + 15 pubkeys * 34 bytes/pubkey = 513 bytes.
==Reference Implementation==
diff --git a/bip-0042.mediawiki b/bip-0042.mediawiki
index 00ac10c..223076f 100644
--- a/bip-0042.mediawiki
+++ b/bip-0042.mediawiki
@@ -5,7 +5,7 @@
Author: Pieter Wuille <pieter.wuille@gmail.com>
Comments-Summary: Unanimously Recommended for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0042
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2014-04-01
License: PD
diff --git a/bip-0061.mediawiki b/bip-0061.mediawiki
index 1e3d41f..b08739d 100644
--- a/bip-0061.mediawiki
+++ b/bip-0061.mediawiki
@@ -83,7 +83,7 @@ the reject message, "client" is the peer that will receive the message.
==== reject version codes ====
-Codes generated during the intial connection process in response to a "version" message:
+Codes generated during the initial connection process in response to a "version" message:
{|
| Code || Description
diff --git a/bip-0098.mediawiki b/bip-0098.mediawiki
index 118a8e2..8540d1a 100644
--- a/bip-0098.mediawiki
+++ b/bip-0098.mediawiki
@@ -57,8 +57,8 @@ The following image depicts an example unbalanced hash-tree:
'''A''', '''B''', and '''C''' are leaf labels, 32-byte double-SHA256 hashes of the data associated with the leaf.
'''Node''' and '''Root''' are inner nodes, whose labels are fast-SHA256 (defined below) hashes of their respective children's labels.
-'''Node''' is labelled with the fast-SHA256 hash of the concatination of '''B''' and '''C'''.
-'''Root''' is labelled with the fast-SHA256 hash of the concatination of '''A''' and '''Node''', and is the ''Merkle root'' of the tree.
+'''Node''' is labelled with the fast-SHA256 hash of the concatenation of '''B''' and '''C'''.
+'''Root''' is labelled with the fast-SHA256 hash of the concatenation of '''A''' and '''Node''', and is the ''Merkle root'' of the tree.
Nodes with single children are not allowed.
The ''double-SHA256'' cryptographic hash function takes an arbitrary-length data as input and produces a 32-byte hash by running the data through the SHA-256 hash function as specified in FIPS 180-4[3], and then running the same hash function again on the 32-byte result, as a protection against length-extension attacks.
@@ -96,7 +96,7 @@ The application of fast-SHA256 to inner node label updates is safe in this limit
so the sorts of attacks prevented by message padding and double-hashing do not apply.
The 'initialization vector' for fast-SHA256 is changed in order to prevent a category of attacks on higher level protocols where a partial collision can serve as both a leaf hash and as an inner node commitment to another leaf hash.
-The IV is computed using standard SHA-256 plus midstate extraction so as to preserve compatability with cryptographic library interfaces that do not support custom IVs, at the cost of a 2x performance hit if neither custom IVs nor resuming from midstate are supported.
+The IV is computed using standard SHA-256 plus midstate extraction so as to preserve compatibility with cryptographic library interfaces that do not support custom IVs, at the cost of a 2x performance hit if neither custom IVs nor resuming from midstate are supported.
The data hashed is a nothing-up-my-sleeve number that is unlikely to have a known hash preimage.
The prime 23 was chosen as the leading fractional bits of the first eight (8) primes, two (2) through nineteen (19), are constants used in the setup of SHA-256 itself.
Using the next prime in sequence reduces the likelihood of introducing weakness due to reuse of a constant factor.
diff --git a/bip-0116.mediawiki b/bip-0116.mediawiki
index 7f103ec..86b0f9a 100644
--- a/bip-0116.mediawiki
+++ b/bip-0116.mediawiki
@@ -69,7 +69,7 @@ A source of malleability in Merkle proofs could potentially lead to spend vulner
For example, a compact 2-of-N policy could be written by using MERKLEBRANCHVERIFY to prove that two keys are extracted from the same tree, one at a time, then checking the proofs for bitwise equality to make sure the same entry wasn't used twice.
With the vulnerable Merkle tree implementation there are privledged positions in unbalanced Merkle trees that allow multiple proofs to be constructed for the same, single entry.
-BIP141 (Segregated Witness)[3] provides support for a powerful form of scirpt upgrades called script versioning, which is able to achieve the sort of upgrades which would previously have been hard-forks.
+BIP141 (Segregated Witness)[3] provides support for a powerful form of script upgrades called script versioning, which is able to achieve the sort of upgrades which would previously have been hard-forks.
If script versioning were used for deployment then MERKLEBRANCHVERIFY could be written to consume its inputs, which would provide a small 2-byte savings for many anticipated use cases.
However the more familiar NOP-expansion soft-fork mechanism used by BIP65 (CHECKLOCKTIMEVERIFY)[5] and BIP112 (CHECKSEQUENCEVERIFY)[6] was chosen over script versioning for the following two reasons:
@@ -99,7 +99,7 @@ The low-order bit of the first parameter, 2, is clear, meaning that there is one
As described by Pieter Wuille[8] the 1-of-N scheme is particularly useful for constructing honeypots.
The desire is to put a large bounty on a server, larger than the value of the server itself so that if the server is compromised it is highly likely that the hacker will claim the bitcoin, thereby revealing the intrusion.
However if there are many servers, e.g. 1,000, it becomes excessively expensive to lock up separate bounties for each server.
-It would be desireable if the same bounty was shared across multiple servers in such a way that the spend would reveal which server was compromised.
+It would be desirable if the same bounty was shared across multiple servers in such a way that the spend would reveal which server was compromised.
This is accomplished by generating 1,000 different keys, building a hash tree of these public keys, and placing each key and associated Merkle path on separate servers.
When the honeypot is claimed, the (previous) owner of the coins can tell which server was compromised from the key and path used to claim the funds.
diff --git a/bip-0117.mediawiki b/bip-0117.mediawiki
index f4d1b4a..4b5706e 100644
--- a/bip-0117.mediawiki
+++ b/bip-0117.mediawiki
@@ -48,7 +48,7 @@ If the above conditions hold except for the last one, such that:
then the top-most element of the main stack is dropped,
and the N=2 (<code>0x51</code>) to 17 (<code>0x60</code>) further elements are popped from the main stack,
continuing from the alt stack if the main stack is exhausted,
-and concatinated together in reverse order to form a serialized script,
+and concatenated together in reverse order to form a serialized script,
which is then executed with the remaining elements of both stacks remaining in place as inputs.
The presence of CHECKSIG or CHECKMULTISIG within the subscript do not count towards the global MAX_BLOCK_SIGOPS_COST limit,
diff --git a/bip-0125.mediawiki b/bip-0125.mediawiki
index b2e3cec..f1e5349 100644
--- a/bip-0125.mediawiki
+++ b/bip-0125.mediawiki
@@ -85,7 +85,7 @@ unconfirmed.
Wallets that don't want to signal replaceability should use either a max
sequence number (0xffffffff) or a sequence number of (0xffffffff-1) when
-then also want to use locktime; all known wallets currently do this.
+they also want to use locktime; all known wallets currently do this.
They should also take care not to spend any unconfirmed transaction that
signals replaceability explicitly or through inherited signaling; most wallets also
currently do this by not spending any unconfirmed transactions except
diff --git a/bip-0143.mediawiki b/bip-0143.mediawiki
index c1332b3..ed07c82 100644
--- a/bip-0143.mediawiki
+++ b/bip-0143.mediawiki
@@ -67,7 +67,7 @@ The item 6 is a 8-byte value of the amount of bitcoin spent in this input.
<code>hashOutputs</code>:
*If the sighash type is neither <code>SINGLE</code> nor <code>NONE</code>, <code>hashOutputs</code> is the double SHA256 of the serialization of all output amount (8-byte little endian) with <code>scriptPubKey</code> (serialized as scripts inside CTxOuts);
*If sighash type is <code>SINGLE</code> and the input index is smaller than the number of outputs, <code>hashOutputs</code> is the double SHA256 of the output amount with <code>scriptPubKey</code> of the same index as the input;
-*Otherwise, <code>hashOutputs</code> is a <code>uint256</code> of <code>0x0000......0000</code>.<ref>In the original algorithm, a <code>uint256</code> of <code>0x0000......0001</code> is committed if the input index for a <code>SINGLE</code> signature is greater than or equal to the number of outputs. In this BIP a <code>0x0000......0000</code> is commited, without changing the semantics.</ref>
+*Otherwise, <code>hashOutputs</code> is a <code>uint256</code> of <code>0x0000......0000</code>.<ref>In the original algorithm, a <code>uint256</code> of <code>0x0000......0001</code> is committed if the input index for a <code>SINGLE</code> signature is greater than or equal to the number of outputs. In this BIP a <code>0x0000......0000</code> is committed, without changing the semantics.</ref>
The <code>hashPrevouts</code>, <code>hashSequence</code>, and <code>hashOutputs</code> calculated in an earlier verification may be reused in other inputs of the same transaction, so that the time complexity of the whole hashing process reduces from O(n<sup>2</sup>) to O(n).
@@ -303,7 +303,7 @@ This example shows how <code>OP_CODESEPARATOR</code> and out-of-range <code>SIGH
scriptCode: 4721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac
^^
- (please note that the not-yet-exectued OP_CODESEPARATOR is not removed from the scriptCode)
+ (please note that the not-yet-executed OP_CODESEPARATOR is not removed from the scriptCode)
preimage: 01000000ef546acf4a020de3898d1b8956176bb507e6211b5ed3619cd08b6ea7e2a09d4100000000000000000000000000000000000000000000000000000000000000000815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f8000000004721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac0011102401000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000003000000
sigHash: 82dde6e4f1e94d02c2b7ad03d2115d691f48d064e9d52f58194a6637e4194391
public key: 026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae
diff --git a/bip-0157.mediawiki b/bip-0157.mediawiki
index 61ffc7e..565a941 100644
--- a/bip-0157.mediawiki
+++ b/bip-0157.mediawiki
@@ -468,4 +468,4 @@ Golomb-Rice Coded sets: https://github.com/Roasbeef/btcutil/tree/gcs/gcs
== Copyright ==
-This document is licensed under the Creative Commons CC0 1.0 Universal lisence.
+This document is licensed under the Creative Commons CC0 1.0 Universal license.
diff --git a/bip-0158.mediawiki b/bip-0158.mediawiki
index 15caa68..bf2e856 100644
--- a/bip-0158.mediawiki
+++ b/bip-0158.mediawiki
@@ -65,11 +65,14 @@ For each block, compact filters are derived containing sets of items associated
with the block (eg. addresses sent to, outpoints spent, etc.). A set of such
data objects is compressed into a probabilistic structure called a
''Golomb-coded set'' (GCS), which matches all items in the set with probability
-1, and matches other items with probability <code>2^(-P)</code> for some integer
-parameter <code>P</code>.
+1, and matches other items with probability <code>2^(-P)</code> for some
+integer parameter <code>P</code>. We also introduce parameter <code>M</code>
+which allows filter to uniquely tune the range that items are hashed onto
+before compressing. Each defined filter also selects distinct parameters for P
+and M.
At a high level, a GCS is constructed from a set of <code>N</code> items by:
-# hashing all items to 64-bit integers in the range <code>[0, N * 2^P)</code>
+# hashing all items to 64-bit integers in the range <code>[0, N * M)</code>
# sorting the hashed values in ascending order
# computing the differences between each value and the previous one
# writing the differences sequentially, compressed with Golomb-Rice coding
@@ -80,9 +83,13 @@ The following sections describe each step in greater detail.
The first step in the filter construction is hashing the variable-sized raw
items in the set to the range <code>[0, F)</code>, where <code>F = N *
-2^P</code>. Set membership queries against the hash outputs will have a false
-positive rate of <code>2^(-P)</code>. To avoid integer overflow, the number of
-items <code>N</code> MUST be <2^32 and <code>P</code> MUST be <=32.
+M</code>. Customarily, <code>M</code> is set to <code>2^P</code>. However, if
+one is able to select both Parameters independently, then more optimal values
+can be
+selected<ref>https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845</ref>.
+Set membership queries against the hash outputs will have a false positive rate
+of <code>2^(-P)</code>. To avoid integer overflow, the
+number of items <code>N</code> MUST be <2^32 and <code>M</code> MUST be <2^32.
The items are first passed through the pseudorandom function ''SipHash'', which
takes a 128-bit key <code>k</code> and a variable-sized byte vector and produces
@@ -104,9 +111,9 @@ result.
hash_to_range(item: []byte, F: uint64, k: [16]byte) -> uint64:
return (siphash(k, item) * F) >> 64
-hashed_set_construct(raw_items: [][]byte, P: uint, k: [16]byte) -> []uint64:
+hashed_set_construct(raw_items: [][]byte, k: [16]byte, M: uint) -> []uint64:
let N = len(raw_items)
- let F = N << P
+ let F = N * M
let set_items = []
@@ -197,8 +204,8 @@ with Golomb-Rice coding. Finally, the bit stream is padded with 0's to the
nearest byte boundary and serialized to the output byte vector.
<pre>
-construct_gcs(L: [][]byte, P: uint, k: [16]byte) -> []byte:
- let set_items = hashed_set_construct(L, P, k)
+construct_gcs(L: [][]byte, P: uint, k: [16]byte, M: uint) -> []byte:
+ let set_items = hashed_set_construct(L, k, M)
set_items.sort()
@@ -224,8 +231,8 @@ against the reconstructed values. Note that querying does not require the entire
decompressed set be held in memory at once.
<pre>
-gcs_match(key: [16]byte, compressed_set: []byte, target: []byte, P: uint, N: uint) -> bool:
- let F = N << P
+gcs_match(key: [16]byte, compressed_set: []byte, target: []byte, P: uint, N: uint, M: uint) -> bool:
+ let F = N * M
let target_hash = hash_to_range(target, F, k)
stream = new_bit_stream(compressed_set)
@@ -258,49 +265,54 @@ against the decompressed GCS contents. See
=== Block Filters ===
-This BIP defines two initial filter types:
+This BIP defines one initial filter type:
* Basic (<code>0x00</code>)
-* Extended (<code>0x01</code>)
+ * <code>M = 784931</code>
+ * <code>P = 19</code>
==== Contents ====
The basic filter is designed to contain everything that a light client needs to
-sync a regular Bitcoin wallet. A basic filter MUST contain exactly the following
-items for each transaction in a block:
-* The outpoint of each input, except for the coinbase transaction
-* The scriptPubKey of each output
-* The <code>txid</code> of the transaction itself
-
-The extended filter contains extra data that is meant to enable applications
-with more advanced smart contracts. An extended filter MUST contain exactly the
-following items for each transaction in a block ''except the coinbase'':
-* Each item within the witness stack of each input (if the input has a witness)
-* Each data push in the scriptSig of each input
-
-Note that neither filter type interprets P2SH scripts or witness scripts to
-extract data pushes from them. If necessary, future filter types may be designed
-to do so.
+sync a regular Bitcoin wallet. A basic filter MUST contain exactly the
+following items for each transaction in a block:
+* The previous output script (the script being spent) for each input, except
+ for the coinbase transaction.
+* The scriptPubKey of each output, aside from all <code>OP_RETURN</code> output
+ scripts.
+
+Any "nil" items MUST NOT be included into the final set of filter elements.
+
+We exclude all <code>OP_RETURN</code> outputs in order to allow filters to
+easily be committed to in the future via a soft-fork. A likely area for future
+commitments is an additional <code>OP_RETURN</code> output in the coinbase
+transaction similar to the current witness commitment
+<ref>https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki</rev>. By
+excluding all <code>OP_RETURN</code> outputs we avoid a circular dependency
+between the commitment, and the item being committed to.
==== Construction ====
-Both the basic and extended filter types are constructed as Golomb-coded sets
-with the following parameters.
+The basic type is constructed as Golomb-coded sets with the following
+parameters.
-The parameter <code>P</code> MUST be set to <code>20</code>. This value was
-chosen as simulations show that it minimizes the bandwidth utilized, considering
-both the expected number of blocks downloaded due to false positives and the
-size of the filters themselves. The code along with a demo used for the
-parameter tuning can be found
-[https://github.com/Roasbeef/bips/blob/83b83c78e189be898573e0bfe936dd0c9b99ecb9/gcs_light_client/gentestvectors.go here].
+The parameter <code>P</code> MUST be set to <code>19</code>, and the parameter
+<code>M</code> MUST be set to <code>784931</code>. Analysis has shown that if
+one is able to select <code>P</code> and <code>M</code> independently, then
+setting <code>M=1.497137 * 2^P</code> is close to optimal
+<ref>https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845</ref>.
+
+Empirical analysis also shows that was chosen as these parameters minimize the
+bandwidth utilized, considering both the expected number of blocks downloaded
+due to false positives and the size of the filters themselves.
The parameter <code>k</code> MUST be set to the first 16 bytes of the hash of
the block for which the filter is constructed. This ensures the key is
deterministic while still varying from block to block.
Since the value <code>N</code> is required to decode a GCS, a serialized GCS
-includes it as a prefix, written as a CompactSize. Thus, the complete
-serialization of a filter is:
-* <code>N</code>, encoded as a CompactSize
+includes it as a prefix, written as a <code>CompactSize</code>. Thus, the
+complete serialization of a filter is:
+* <code>N</code>, encoded as a <code>CompactSize</code>
* The bytes of the compressed filter itself
==== Signaling ====
@@ -323,7 +335,8 @@ though it requires implementation of the new filters.
We would like to thank bfd (from the bitcoin-dev mailing list) for bringing the
basis of this BIP to our attention, Greg Maxwell for pointing us in the
-direction of Golomb-Rice coding and fast range optimization, and Pedro
+direction of Golomb-Rice coding and fast range optimization, Pieter Wullie for
+his analysis of optimal GCS parameters, and Pedro
Martelletto for writing the initial indexing code for <code>btcd</code>.
We would also like to thank Dave Collins, JJ Jeffrey, and Eric Lombrozo for
@@ -375,8 +388,8 @@ easier to understand.
=== Golomb-Coded Set Multi-Match ===
<pre>
-gcs_match_any(key: [16]byte, compressed_set: []byte, targets: [][]byte, P: uint, N: uint) -> bool:
- let F = N << P
+gcs_match_any(key: [16]byte, compressed_set: []byte, targets: [][]byte, P: uint, N: uint, M: uint) -> bool:
+ let F = N * M
// Map targets to the same range as the set hashes.
let target_hashes = []
diff --git a/bip-0158/gentestvectors.go b/bip-0158/gentestvectors.go
index deaf2c7..472f8c1 100644
--- a/bip-0158/gentestvectors.go
+++ b/bip-0158/gentestvectors.go
@@ -15,13 +15,15 @@ import (
"io"
"io/ioutil"
"os"
- "path"
+ "path/filepath"
- "github.com/roasbeef/btcd/chaincfg/chainhash"
- "github.com/roasbeef/btcd/rpcclient"
- "github.com/roasbeef/btcd/wire"
- "github.com/roasbeef/btcutil/gcs"
- "github.com/roasbeef/btcutil/gcs/builder"
+ "github.com/btcsuite/btcd/blockchain"
+ "github.com/btcsuite/btcd/chaincfg/chainhash"
+ "github.com/btcsuite/btcd/rpcclient"
+ "github.com/btcsuite/btcd/wire"
+ "github.com/btcsuite/btcutil"
+ "github.com/btcsuite/btcutil/gcs/builder"
+ "github.com/davecgh/go-spew/spew"
)
var (
@@ -29,13 +31,19 @@ var (
// vectors. Any new entries must be added in sorted order.
testBlockHeights = []testBlockCase{
{0, "Genesis block"},
- {1, "Extended filter is empty"},
{2, ""},
{3, ""},
{926485, "Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"},
{987876, "Coinbase tx has unparseable output script"},
{1263442, "Includes witness data"},
}
+
+ defaultBtcdDir = btcutil.AppDataDir("btcd", false)
+ defaultBtcdRPCCertFile = filepath.Join(defaultBtcdDir, "rpc.cert")
+)
+
+const (
+ fp = 19
)
type testBlockCase struct {
@@ -86,41 +94,78 @@ func (w *JSONTestWriter) Close() error {
return err
}
-func main() {
- err := os.Mkdir("gcstestvectors", os.ModeDir|0755)
- if err != nil { // Don't overwrite existing output if any
- fmt.Println("Couldn't create directory: ", err)
- return
- }
- files := make([]*JSONTestWriter, 33)
- prevBasicHeaders := make([]chainhash.Hash, 33)
- prevExtHeaders := make([]chainhash.Hash, 33)
- for i := 1; i <= 32; i++ { // Min 1 bit of collision space, max 32
- fName := fmt.Sprintf("gcstestvectors/testnet-%02d.json", i)
- file, err := os.Create(fName)
- if err != nil {
- fmt.Println("Error creating output file: ", err.Error())
- return
+func fetchPrevOutputScripts(client *rpcclient.Client, block *wire.MsgBlock) ([][]byte, error) {
+ var prevScripts [][]byte
+
+ txCache := make(map[chainhash.Hash]*wire.MsgTx)
+ for _, tx := range block.Transactions {
+ if blockchain.IsCoinBaseTx(tx) {
+ continue
}
- defer file.Close()
- writer := &JSONTestWriter{writer: file}
- defer writer.Close()
+ for _, txIn := range tx.TxIn {
+ prevOp := txIn.PreviousOutPoint
- err = writer.WriteComment("Block Height,Block Hash,Block,Previous Basic Header,Previous Ext Header,Basic Filter,Ext Filter,Basic Header,Ext Header,Notes")
- if err != nil {
- fmt.Println("Error writing to output file: ", err.Error())
- return
+ tx, ok := txCache[prevOp.Hash]
+ if !ok {
+ originTx, err := client.GetRawTransaction(
+ &prevOp.Hash,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("unable to get "+
+ "txid=%v: %v", prevOp.Hash, err)
+ }
+
+ txCache[prevOp.Hash] = originTx.MsgTx()
+
+ tx = originTx.MsgTx()
+ }
+
+ index := prevOp.Index
+
+ prevScripts = append(
+ prevScripts, tx.TxOut[index].PkScript,
+ )
}
+ }
- files[i] = writer
+ return prevScripts, nil
+}
+
+func main() {
+ var (
+ writerFile *JSONTestWriter
+ prevBasicHeader chainhash.Hash
+ )
+ fName := fmt.Sprintf("testnet-%02d.json", fp)
+ file, err := os.Create(fName)
+ if err != nil {
+ fmt.Println("Error creating output file: ", err.Error())
+ return
+ }
+ defer file.Close()
+
+ writer := &JSONTestWriter{
+ writer: file,
+ }
+ defer writer.Close()
+
+ err = writer.WriteComment("Block Height,Block Hash,Block," +
+ "[Prev Output Scripts for Block],Previous Basic Header," +
+ "Basic Filter,Basic Header,Notes")
+ if err != nil {
+ fmt.Println("Error writing to output file: ", err.Error())
+ return
}
- cert, err := ioutil.ReadFile(
- path.Join(os.Getenv("HOME"), "/.btcd/rpc.cert"))
+
+ writerFile = writer
+
+ cert, err := ioutil.ReadFile(defaultBtcdRPCCertFile)
if err != nil {
fmt.Println("Couldn't read RPC cert: ", err.Error())
return
}
+
conf := rpcclient.ConnConfig{
Host: "127.0.0.1:18334",
Endpoint: "ws",
@@ -134,19 +179,20 @@ func main() {
return
}
- var testBlockIndex int = 0
+ var testBlockIndex int
for height := 0; testBlockIndex < len(testBlockHeights); height++ {
- fmt.Printf("Height: %d\n", height)
blockHash, err := client.GetBlockHash(int64(height))
if err != nil {
fmt.Println("Couldn't get block hash: ", err.Error())
return
}
+
block, err := client.GetBlock(blockHash)
if err != nil {
fmt.Println("Couldn't get block hash: ", err.Error())
return
}
+
var blockBuf bytes.Buffer
err = block.Serialize(&blockBuf)
if err != nil {
@@ -154,208 +200,98 @@ func main() {
return
}
blockBytes := blockBuf.Bytes()
- for i := 1; i <= 32; i++ {
- basicFilter, err := buildBasicFilter(block, uint8(i))
- if err != nil {
- fmt.Println("Error generating basic filter: ", err.Error())
- return
- }
- basicHeader, err := builder.MakeHeaderForFilter(basicFilter,
- prevBasicHeaders[i])
- if err != nil {
- fmt.Println("Error generating header for filter: ", err.Error())
- return
- }
- if basicFilter == nil {
- basicFilter = &gcs.Filter{}
- }
- extFilter, err := buildExtFilter(block, uint8(i))
- if err != nil {
- fmt.Println("Error generating ext filter: ", err.Error())
- return
- }
- extHeader, err := builder.MakeHeaderForFilter(extFilter,
- prevExtHeaders[i])
- if err != nil {
- fmt.Println("Error generating header for filter: ", err.Error())
- return
- }
- if extFilter == nil {
- extFilter = &gcs.Filter{}
- }
- if i == builder.DefaultP { // This is the default filter size so we can check against the server's info
- filter, err := client.GetCFilter(blockHash, wire.GCSFilterRegular)
- if err != nil {
- fmt.Println("Error getting basic filter: ", err.Error())
- return
- }
- nBytes, err := basicFilter.NBytes()
- if err != nil {
- fmt.Println("Couldn't get NBytes(): ", err)
- return
- }
- if !bytes.Equal(filter.Data, nBytes) {
- // Don't error on empty filters
- fmt.Println("Basic filter doesn't match!\n", filter.Data, "\n", nBytes)
- return
- }
- filter, err = client.GetCFilter(blockHash, wire.GCSFilterExtended)
- if err != nil {
- fmt.Println("Error getting extended filter: ", err.Error())
- return
- }
- nBytes, err = extFilter.NBytes()
- if err != nil {
- fmt.Println("Couldn't get NBytes(): ", err)
- return
- }
- if !bytes.Equal(filter.Data, nBytes) {
- fmt.Println("Extended filter doesn't match!")
- return
- }
- header, err := client.GetCFilterHeader(blockHash, wire.GCSFilterRegular)
- if err != nil {
- fmt.Println("Error getting basic header: ", err.Error())
- return
- }
- if !bytes.Equal(header.PrevFilterHeader[:], basicHeader[:]) {
- fmt.Println("Basic header doesn't match!")
- return
- }
- header, err = client.GetCFilterHeader(blockHash, wire.GCSFilterExtended)
- if err != nil {
- fmt.Println("Error getting extended header: ", err.Error())
- return
- }
- if !bytes.Equal(header.PrevFilterHeader[:], extHeader[:]) {
- fmt.Println("Extended header doesn't match!")
- return
- }
- fmt.Println("Verified against server")
- }
- if uint32(height) == testBlockHeights[testBlockIndex].height {
- var bfBytes []byte
- var efBytes []byte
- bfBytes, err = basicFilter.NBytes()
- if err != nil {
- fmt.Println("Couldn't get NBytes(): ", err)
- return
- }
- efBytes, err = extFilter.NBytes()
- if err != nil {
- fmt.Println("Couldn't get NBytes(): ", err)
- return
- }
- row := []interface{}{
- height,
- blockHash.String(),
- hex.EncodeToString(blockBytes),
- prevBasicHeaders[i].String(),
- prevExtHeaders[i].String(),
- hex.EncodeToString(bfBytes),
- hex.EncodeToString(efBytes),
- basicHeader.String(),
- extHeader.String(),
- testBlockHeights[testBlockIndex].comment,
- }
- err = files[i].WriteTestCase(row)
- if err != nil {
- fmt.Println("Error writing test case to output: ", err.Error())
- return
- }
- }
- prevBasicHeaders[i] = basicHeader
- prevExtHeaders[i] = extHeader
+ prevOutputScripts, err := fetchPrevOutputScripts(client, block)
+ if err != nil {
+ fmt.Println("Couldn't fetch prev output scipts: ", err)
+ return
}
- if uint32(height) == testBlockHeights[testBlockIndex].height {
- testBlockIndex++
+ basicFilter, err := builder.BuildBasicFilter(block, prevOutputScripts)
+ if err != nil {
+ fmt.Println("Error generating basic filter: ", err.Error())
+ return
+ }
+ basicHeader, err := builder.MakeHeaderForFilter(basicFilter, prevBasicHeader)
+ if err != nil {
+ fmt.Println("Error generating header for filter: ", err.Error())
+ return
}
- }
-}
-// buildBasicFilter builds a basic GCS filter from a block. A basic GCS filter
-// will contain all the previous outpoints spent within a block, as well as the
-// data pushes within all the outputs created within a block. p is specified as
-// an argument in order to create test vectors with various values for p.
-func buildBasicFilter(block *wire.MsgBlock, p uint8) (*gcs.Filter, error) {
- blockHash := block.BlockHash()
- b := builder.WithKeyHashP(&blockHash, p)
-
- // If the filter had an issue with the specified key, then we force it
- // to bubble up here by calling the Key() function.
- _, err := b.Key()
- if err != nil {
- return nil, err
- }
+ // We'll now ensure that we've constructed the same filter as
+ // the chain server we're fetching blocks form.
+ filter, err := client.GetCFilter(
+ blockHash, wire.GCSFilterRegular,
+ )
+ if err != nil {
+ fmt.Println("Error getting basic filter: ",
+ err.Error())
+ return
+ }
- // In order to build a basic filter, we'll range over the entire block,
- // adding the outpoint data as well as the data pushes within the
- // pkScript.
- for i, tx := range block.Transactions {
- // First we'll compute the bash of the transaction and add that
- // directly to the filter.
- txHash := tx.TxHash()
- b.AddHash(&txHash)
-
- // Skip the inputs for the coinbase transaction
- if i != 0 {
- // Each each txin, we'll add a serialized version of
- // the txid:index to the filters data slices.
- for _, txIn := range tx.TxIn {
- b.AddOutPoint(txIn.PreviousOutPoint)
- }
+ nBytes, err := basicFilter.NBytes()
+ if err != nil {
+ fmt.Println("Couldn't get NBytes(): ", err)
+ return
+ }
+ if !bytes.Equal(filter.Data, nBytes) {
+ // Don't error on empty filters
+ fmt.Printf("basic filter doesn't match: generated "+
+ "%x, rpc returns %x, block %v", nBytes,
+ filter.Data, spew.Sdump(block))
+ return
}
- // For each output in a transaction, we'll add each of the
- // individual data pushes within the script.
- for _, txOut := range tx.TxOut {
- b.AddEntry(txOut.PkScript)
+ header, err := client.GetCFilterHeader(
+ blockHash, wire.GCSFilterRegular,
+ )
+ if err != nil {
+ fmt.Println("Error getting basic header: ", err.Error())
+ return
+ }
+ if !bytes.Equal(header.PrevFilterHeader[:], basicHeader[:]) {
+ fmt.Println("Basic header doesn't match!")
+ return
}
- }
- return b.Build()
-}
+ if height%1000 == 0 {
+ fmt.Printf("Verified height %v against server\n", height)
+ }
-// buildExtFilter builds an extended GCS filter from a block. An extended
-// filter supplements a regular basic filter by include all the _witness_ data
-// found within a block. This includes all the data pushes within any signature
-// scripts as well as each element of an input's witness stack. Additionally,
-// the _hashes_ of each transaction are also inserted into the filter. p is
-// specified as an argument in order to create test vectors with various values
-// for p.
-func buildExtFilter(block *wire.MsgBlock, p uint8) (*gcs.Filter, error) {
- blockHash := block.BlockHash()
- b := builder.WithKeyHashP(&blockHash, p)
-
- // If the filter had an issue with the specified key, then we force it
- // to bubble up here by calling the Key() function.
- _, err := b.Key()
- if err != nil {
- return nil, err
- }
+ if uint32(height) == testBlockHeights[testBlockIndex].height {
+ var bfBytes []byte
+ bfBytes, err = basicFilter.NBytes()
+ if err != nil {
+ fmt.Println("Couldn't get NBytes(): ", err)
+ return
+ }
- // In order to build an extended filter, we add the hash of each
- // transaction as well as each piece of witness data included in both
- // the sigScript and the witness stack of an input.
- for i, tx := range block.Transactions {
- // Skip the inputs for the coinbase transaction
- if i != 0 {
- // Next, for each input, we'll add the sigScript (if
- // it's present), and also the witness stack (if it's
- // present)
- for _, txIn := range tx.TxIn {
- if txIn.SignatureScript != nil {
- b.AddScript(txIn.SignatureScript)
- }
+ prevScriptStrings := make([]string, len(prevOutputScripts))
+ for i, prevScript := range prevOutputScripts {
+ prevScriptStrings[i] = hex.EncodeToString(prevScript)
+ }
- if len(txIn.Witness) != 0 {
- b.AddWitness(txIn.Witness)
- }
+ row := []interface{}{
+ height,
+ blockHash.String(),
+ hex.EncodeToString(blockBytes),
+ prevScriptStrings,
+ prevBasicHeader.String(),
+ hex.EncodeToString(bfBytes),
+ basicHeader.String(),
+ testBlockHeights[testBlockIndex].comment,
+ }
+ err = writerFile.WriteTestCase(row)
+ if err != nil {
+ fmt.Println("Error writing test case to output: ", err.Error())
+ return
}
}
- }
- return b.Build()
+ prevBasicHeader = basicHeader
+
+ if uint32(height) == testBlockHeights[testBlockIndex].height {
+ testBlockIndex++
+ }
+ }
}
diff --git a/bip-0158/testnet-20.json b/bip-0158/testnet-19.json
index a768b49..2f00728 100644
--- a/bip-0158/testnet-20.json
+++ b/bip-0158/testnet-19.json
@@ -1,10 +1,9 @@
[
-["Block Height,Block Hash,Block,Previous Basic Header,Previous Ext Header,Basic Filter,Ext Filter,Basic Header,Ext Header,Notes"],
-[0,"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943","0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000","0000000000000000000000000000000000000000000000000000000000000000","0000000000000000000000000000000000000000000000000000000000000000","0285c7cdbe33a0","00","c0589c7f567cffaf7bc0c9f6ad61710b78d3c1afef5d65a2a08e8a753173aa54","753e0d1c28585269ab770b166ca2cd1b32f9bc918750547941ed4849d5a80ba8","Genesis block"],
-[1,"00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206","0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0420e7494d017f062f503253482fffffffff0100f2052a010000002321021aeaf2f8638a129a3156fbe7e5ef635226b0bafd495ff03afe2c843d7e3a4b51ac00000000","c0589c7f567cffaf7bc0c9f6ad61710b78d3c1afef5d65a2a08e8a753173aa54","753e0d1c28585269ab770b166ca2cd1b32f9bc918750547941ed4849d5a80ba8","026929d09bee00","00","81e4f3e934488be62758f0b88037aa558262da3190ca018329997a319a0f8b5b","31b674ab635e074717329dabdb25d3cb0e14cb2526000cc2cedac7b5f2595110","Extended filter is empty"],
-[2,"000000006c02c8ea6e4ff69651f7fcde348fb9d557a06e6957b65552002a7820","0100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d235340101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0432e7494d010e062f503253482fffffffff0100f2052a010000002321038a7f6ef1c8ca0c588aa53fa860128077c9e6c11e6830f4d7ee4e763a56b7718fac00000000","81e4f3e934488be62758f0b88037aa558262da3190ca018329997a319a0f8b5b","31b674ab635e074717329dabdb25d3cb0e14cb2526000cc2cedac7b5f2595110","0278fc41168ec0","00","ec48f9f8a625bd8adb2d2684867a05baafebf935553e0b78b386da98179dcf49","0dd53b407c3f242f1838e39e2fc0cfb89cdca27de07ec230568a08d1872f9e01",""],
-[3,"000000008b896e272758da5297bcd98fdc6d97c9b765ecec401e286dc1fdbe10","0100000020782a005255b657696ea057d5b98f34defcf75196f64f6eeac8026c0000000041ba5afc532aae03151b8aa87b65e1594f97504a768e010c98c0add79216247186e7494dffff001d058dc2b60101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0486e7494d0151062f503253482fffffffff0100f2052a01000000232103f6d9ff4c12959445ca5549c811683bf9c88e637b222dd2e0311154c4c85cf423ac00000000","ec48f9f8a625bd8adb2d2684867a05baafebf935553e0b78b386da98179dcf49","0dd53b407c3f242f1838e39e2fc0cfb89cdca27de07ec230568a08d1872f9e01","022ce4b3256540","00","060b7e1be150cc3cabd9e96b00af217132b387f31fd2bd9adfb0c7f5a09a3356","5b2a59bc476d52b45de1398ee34ed10d0cccd2a4b19ba502a456c7356b35be0d",""],
-[926485,"000000000000015d6077a411a8f5cc95caf775ccf11c54e27df75ce58d187313","0000002060bbab0edbf3ef8a49608ee326f8fd75c473b7e3982095e2d100000000000000c30134f8c9b6d2470488d7a67a888f6fa12f8692e0c3411fbfb92f0f68f67eedae03ca57ef13021acc22dc4105010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2f0315230e0004ae03ca57043e3d1e1d0c8796bf579aef0c0000000000122f4e696e6a61506f6f6c2f5345475749542fffffffff038427a112000000001976a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac0000000000000000266a24aa21a9ed5c748e121c0fe146d973a4ac26fa4a68b0549d46ee22d25f50a5e46fe1b377ee00000000000000002952534b424c4f434b3acd16772ad61a3c5f00287480b720f6035d5e54c9efc71be94bb5e3727f10909001200000000000000000000000000000000000000000000000000000000000000000000000000100000000010145310e878941a1b2bc2d33797ee4d89d95eaaf2e13488063a2aa9a74490f510a0100000023220020b6744de4f6ec63cc92f7c220cdefeeb1b1bed2b66c8e5706d80ec247d37e65a1ffffffff01002d3101000000001976a9143ebc40e411ed3c76f86711507ab952300890397288ac0400473044022001dd489a5d4e2fbd8a3ade27177f6b49296ba7695c40dbbe650ea83f106415fd02200b23a0602d8ff1bdf79dee118205fc7e9b40672bf31563e5741feb53fb86388501483045022100f88f040e90cc5dc6c6189d04718376ac19ed996bf9e4a3c29c3718d90ffd27180220761711f16c9e3a44f71aab55cbc0634907a1fa8bb635d971a9a01d368727bea10169522103b3623117e988b76aaabe3d63f56a4fc88b228a71e64c4cc551d1204822fe85cb2103dd823066e096f72ed617a41d3ca56717db335b1ea47a1b4c5c9dbdd0963acba621033d7c89bd9da29fa8d44db7906a9778b53121f72191184a9fee785c39180e4be153ae00000000010000000120925534261de4dcebb1ed5ab1b62bfe7a3ef968fb111dc2c910adfebc6e3bdf010000006b483045022100f50198f5ae66211a4f485190abe4dc7accdabe3bc214ebc9ea7069b97097d46e0220316a70a03014887086e335fc1b48358d46cd6bdc9af3b57c109c94af76fc915101210316cff587a01a2736d5e12e53551b18d73780b83c3bfb4fcf209c869b11b6415effffffff0220a10700000000001976a91450333046115eaa0ac9e0216565f945070e44573988ac2e7cd01a000000001976a914c01a7ca16b47be50cbdbc60724f701d52d75156688ac00000000010000000203a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322010000006a47304402204efc3d70e4ca3049c2a425025edf22d5ca355f9ec899dbfbbeeb2268533a0f2b02204780d3739653035af4814ea52e1396d021953f948c29754edd0ee537364603dc012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff03a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322000000006a47304402202d96defdc5b4af71d6ba28c9a6042c2d5ee7bc6de565d4db84ef517445626e03022022da80320e9e489c8f41b74833dfb6a54a4eb5087cdb46eb663eef0b25caa526012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a914b7e6f7ff8658b2d1fb107e3d7be7af4742e6b1b3876f88fc00000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac0000000001000000043ffd60d3818431c495b89be84afac205d5d1ed663009291c560758bbd0a66df5010000006b483045022100f344607de9df42049688dcae8ff1db34c0c7cd25ec05516e30d2bc8f12ac9b2f022060b648f6a21745ea6d9782e17bcc4277b5808326488a1f40d41e125879723d3a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffffa5379401cce30f84731ef1ba65ce27edf2cc7ce57704507ebe8714aa16a96b92010000006a473044022020c37a63bf4d7f564c2192528709b6a38ab8271bd96898c6c2e335e5208661580220435c6f1ad4d9305d2c0a818b2feb5e45d443f2f162c0f61953a14d097fd07064012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff70e731e193235ff12c3184510895731a099112ffca4b00246c60003c40f843ce000000006a473044022053760f74c29a879e30a17b5f03a5bb057a5751a39f86fa6ecdedc36a1b7db04c022041d41c9b95f00d2d10a0373322a9025dba66c942196bc9d8adeb0e12d3024728012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff66b7a71b3e50379c8e85fc18fe3f1a408fc985f257036c34702ba205cef09f6f000000006a4730440220499bf9e2db3db6e930228d0661395f65431acae466634d098612fd80b08459ee022040e069fc9e3c60009f521cef54c38aadbd1251aee37940e6018aadb10f194d6a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a9148fc37ad460fdfbd2b44fe446f6e3071a4f64faa6878f447f0b000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac00000000","5c169b91332e661a4ebf684d6dffcf64aa139e1e736096ce462609b2e0783c55","5f3cd111e10ed28b7c2bc138fe4bc62e5df1cdc292c010b78c84e5111a5daaa6","16040c63f7ddea293f2d9c13690c0ba7b2910228c38b0fe542ce525021e49b598ada05f83bb9c37c711a02b1850265991c34c4fea6261d22a4b84596c0","0e6651beff00ee7a3be424a90e98450727b304558434c8d53781d469131ad21d399376c151ca28","c8f83ffbc9781c2bd4b7e3c055e888b00d3e2fea14e93b3c4f3adee86b063374","61f8ee615258981089be9f98337f53f44b14cc1532aa469a348fdee547117b80","Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"],
-[987876,"0000000000000c00901f2049055e2a437c819d79a3d54fd63e6af796cd7b8a79","000000202694f74969fdb542090e95a56bc8aa2d646e27033850e32f1c5f000000000000f7e53676b3f12d5beb524ed617f2d25f5a93b5f4f52c1ba2678260d72712f8dd0a6dfe5740257e1a4b1768960101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1603e4120ff9c30a1c216900002f424d4920546573742fffffff0001205fa012000000001e76a914c486de584a735ec2f22da7cd9681614681f92173d83d0aa68688ac00000000","37bf9e681888b3cd204ca4e0c995aad68cd0ecb86bdf19dd0fa2e72dbabcda28","c4c5051dd741c11840ef3f11fb4f372a16bb5aac1dc66576e89e8e6835d667e0","021016dc7a6a20","00","156e9bf3ec5be367f0a829858e9ee182cc3a6531bedced491a52fcfed841c6cb","cab50aab93410cb150fd761f2067a909d35c8a9c0114578efd9590e2d381ee02","Coinbase tx has unparseable output script"],
-[1263442,"000000006f27ddfe1dd680044a34548f41bed47eba9e6f0b310da21423bc5f33","000000201c8d1a529c39a396db2db234d5ec152fa651a2872966daccbde028b400000000083f14492679151dbfaa1a825ef4c18518e780c1f91044180280a7d33f4a98ff5f45765aaddc001d38333b9a02010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff230352471300fe5f45765afe94690a000963676d696e6572343208000000000000000000ffffffff024423a804000000001976a914f2c25ac3d59f3d674b1d1d0a25c27339aaac0ba688ac0000000000000000266a24aa21a9edcb26cb3052426b9ebb4d19c819ef87c19677bbf3a7c46ef0855bd1b2abe83491012000000000000000000000000000000000000000000000000000000000000000000000000002000000000101d20978463906ba4ff5e7192494b88dd5eb0de85d900ab253af909106faa22cc5010000000004000000014777ff000000000016001446c29eabe8208a33aa1023c741fa79aa92e881ff0347304402207d7ca96134f2bcfdd6b536536fdd39ad17793632016936f777ebb32c22943fda02206014d2fb8a6aa58279797f861042ba604ebd2f8f61e5bddbd9d3be5a245047b201004b632103eeaeba7ce5dc2470221e9517fb498e8d6bd4e73b85b8be655196972eb9ccd5566754b2752103a40b74d43df244799d041f32ce1ad515a6cd99501701540e38750d883ae21d3a68ac00000000","da6984906c48525f1d800b0e9b480b5fde1a3a32ad7e4cac6a0566d86b9b01a5","7820f3d2397d77068f0f0c824c4f403db89682e5ab6e82d027cb84d7beb8a08c","06970f05e70c2ec63508cdf07609cb8434","03049063c6b4e9a028","5a369775edcb1dcde9bbc88f0897bd3fd9ab0317d2906e8c10b62641c2104c54","73cee3d4b37b689f5da7251f175ff4630f2c142d7399b407d5cac65bc593b68d","Includes witness data"]
+["Block Height,Block Hash,Block,[Prev Output Scripts for Block],Previous Basic Header,Basic Filter,Basic Header,Notes"],
+[0,"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943","0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",[],"0000000000000000000000000000000000000000000000000000000000000000","019dfca8","21584579b7eb08997773e5aeff3a7f932700042d0ed2a6129012b7d7ae81b750","Genesis block"],
+[2,"000000006c02c8ea6e4ff69651f7fcde348fb9d557a06e6957b65552002a7820","0100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d235340101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0432e7494d010e062f503253482fffffffff0100f2052a010000002321038a7f6ef1c8ca0c588aa53fa860128077c9e6c11e6830f4d7ee4e763a56b7718fac00000000",[],"d7bdac13a59d745b1add0d2ce852f1a0442e8945fc1bf3848d3cbffd88c24fe1","0174a170","186afd11ef2b5e7e3504f2e8cbf8df28a1fd251fe53d60dff8b1467d1b386cf0",""],
+[3,"000000008b896e272758da5297bcd98fdc6d97c9b765ecec401e286dc1fdbe10","0100000020782a005255b657696ea057d5b98f34defcf75196f64f6eeac8026c0000000041ba5afc532aae03151b8aa87b65e1594f97504a768e010c98c0add79216247186e7494dffff001d058dc2b60101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0486e7494d0151062f503253482fffffffff0100f2052a01000000232103f6d9ff4c12959445ca5549c811683bf9c88e637b222dd2e0311154c4c85cf423ac00000000",[],"186afd11ef2b5e7e3504f2e8cbf8df28a1fd251fe53d60dff8b1467d1b386cf0","016cf7a0","8d63aadf5ab7257cb6d2316a57b16f517bff1c6388f124ec4c04af1212729d2a",""],
+[926485,"000000000000015d6077a411a8f5cc95caf775ccf11c54e27df75ce58d187313","0000002060bbab0edbf3ef8a49608ee326f8fd75c473b7e3982095e2d100000000000000c30134f8c9b6d2470488d7a67a888f6fa12f8692e0c3411fbfb92f0f68f67eedae03ca57ef13021acc22dc4105010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2f0315230e0004ae03ca57043e3d1e1d0c8796bf579aef0c0000000000122f4e696e6a61506f6f6c2f5345475749542fffffffff038427a112000000001976a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac0000000000000000266a24aa21a9ed5c748e121c0fe146d973a4ac26fa4a68b0549d46ee22d25f50a5e46fe1b377ee00000000000000002952534b424c4f434b3acd16772ad61a3c5f00287480b720f6035d5e54c9efc71be94bb5e3727f10909001200000000000000000000000000000000000000000000000000000000000000000000000000100000000010145310e878941a1b2bc2d33797ee4d89d95eaaf2e13488063a2aa9a74490f510a0100000023220020b6744de4f6ec63cc92f7c220cdefeeb1b1bed2b66c8e5706d80ec247d37e65a1ffffffff01002d3101000000001976a9143ebc40e411ed3c76f86711507ab952300890397288ac0400473044022001dd489a5d4e2fbd8a3ade27177f6b49296ba7695c40dbbe650ea83f106415fd02200b23a0602d8ff1bdf79dee118205fc7e9b40672bf31563e5741feb53fb86388501483045022100f88f040e90cc5dc6c6189d04718376ac19ed996bf9e4a3c29c3718d90ffd27180220761711f16c9e3a44f71aab55cbc0634907a1fa8bb635d971a9a01d368727bea10169522103b3623117e988b76aaabe3d63f56a4fc88b228a71e64c4cc551d1204822fe85cb2103dd823066e096f72ed617a41d3ca56717db335b1ea47a1b4c5c9dbdd0963acba621033d7c89bd9da29fa8d44db7906a9778b53121f72191184a9fee785c39180e4be153ae00000000010000000120925534261de4dcebb1ed5ab1b62bfe7a3ef968fb111dc2c910adfebc6e3bdf010000006b483045022100f50198f5ae66211a4f485190abe4dc7accdabe3bc214ebc9ea7069b97097d46e0220316a70a03014887086e335fc1b48358d46cd6bdc9af3b57c109c94af76fc915101210316cff587a01a2736d5e12e53551b18d73780b83c3bfb4fcf209c869b11b6415effffffff0220a10700000000001976a91450333046115eaa0ac9e0216565f945070e44573988ac2e7cd01a000000001976a914c01a7ca16b47be50cbdbc60724f701d52d75156688ac00000000010000000203a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322010000006a47304402204efc3d70e4ca3049c2a425025edf22d5ca355f9ec899dbfbbeeb2268533a0f2b02204780d3739653035af4814ea52e1396d021953f948c29754edd0ee537364603dc012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff03a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322000000006a47304402202d96defdc5b4af71d6ba28c9a6042c2d5ee7bc6de565d4db84ef517445626e03022022da80320e9e489c8f41b74833dfb6a54a4eb5087cdb46eb663eef0b25caa526012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a914b7e6f7ff8658b2d1fb107e3d7be7af4742e6b1b3876f88fc00000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac0000000001000000043ffd60d3818431c495b89be84afac205d5d1ed663009291c560758bbd0a66df5010000006b483045022100f344607de9df42049688dcae8ff1db34c0c7cd25ec05516e30d2bc8f12ac9b2f022060b648f6a21745ea6d9782e17bcc4277b5808326488a1f40d41e125879723d3a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffffa5379401cce30f84731ef1ba65ce27edf2cc7ce57704507ebe8714aa16a96b92010000006a473044022020c37a63bf4d7f564c2192528709b6a38ab8271bd96898c6c2e335e5208661580220435c6f1ad4d9305d2c0a818b2feb5e45d443f2f162c0f61953a14d097fd07064012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff70e731e193235ff12c3184510895731a099112ffca4b00246c60003c40f843ce000000006a473044022053760f74c29a879e30a17b5f03a5bb057a5751a39f86fa6ecdedc36a1b7db04c022041d41c9b95f00d2d10a0373322a9025dba66c942196bc9d8adeb0e12d3024728012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff66b7a71b3e50379c8e85fc18fe3f1a408fc985f257036c34702ba205cef09f6f000000006a4730440220499bf9e2db3db6e930228d0661395f65431acae466634d098612fd80b08459ee022040e069fc9e3c60009f521cef54c38aadbd1251aee37940e6018aadb10f194d6a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a9148fc37ad460fdfbd2b44fe446f6e3071a4f64faa6878f447f0b000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac00000000",["a914feb8a29635c56d9cd913122f90678756bf23887687","76a914c01a7ca16b47be50cbdbc60724f701d52d75156688ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac"],"da49977ba1ee0d620a2c4f8f646b03cd0d230f5c6c994722e3ba884889f0be1a","09027acea61b6cc3fb33f5d52f7d088a6b2f75d234e89ca800","4cd9dd007a325199102f1fc0b7d77ca25ee3c84d46018c4353ecfcb56c0d3e7a","Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"],
+[987876,"0000000000000c00901f2049055e2a437c819d79a3d54fd63e6af796cd7b8a79","000000202694f74969fdb542090e95a56bc8aa2d646e27033850e32f1c5f000000000000f7e53676b3f12d5beb524ed617f2d25f5a93b5f4f52c1ba2678260d72712f8dd0a6dfe5740257e1a4b1768960101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1603e4120ff9c30a1c216900002f424d4920546573742fffffff0001205fa012000000001e76a914c486de584a735ec2f22da7cd9681614681f92173d83d0aa68688ac00000000",[],"e9d729b72d533c29abe5276d5cf6c152f3723f10efe000b1e0c9ca5265a8beb6","010c0b40","e6137ae5a8424c40da1e5023c16975cc97b09300b4c050e6b1c713add3836c40","Coinbase tx has unparseable output script"],
+[1263442,"000000006f27ddfe1dd680044a34548f41bed47eba9e6f0b310da21423bc5f33","000000201c8d1a529c39a396db2db234d5ec152fa651a2872966daccbde028b400000000083f14492679151dbfaa1a825ef4c18518e780c1f91044180280a7d33f4a98ff5f45765aaddc001d38333b9a02010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff230352471300fe5f45765afe94690a000963676d696e6572343208000000000000000000ffffffff024423a804000000001976a914f2c25ac3d59f3d674b1d1d0a25c27339aaac0ba688ac0000000000000000266a24aa21a9edcb26cb3052426b9ebb4d19c819ef87c19677bbf3a7c46ef0855bd1b2abe83491012000000000000000000000000000000000000000000000000000000000000000000000000002000000000101d20978463906ba4ff5e7192494b88dd5eb0de85d900ab253af909106faa22cc5010000000004000000014777ff000000000016001446c29eabe8208a33aa1023c741fa79aa92e881ff0347304402207d7ca96134f2bcfdd6b536536fdd39ad17793632016936f777ebb32c22943fda02206014d2fb8a6aa58279797f861042ba604ebd2f8f61e5bddbd9d3be5a245047b201004b632103eeaeba7ce5dc2470221e9517fb498e8d6bd4e73b85b8be655196972eb9ccd5566754b2752103a40b74d43df244799d041f32ce1ad515a6cd99501701540e38750d883ae21d3a68ac00000000",["002027a5000c7917f785d8fc6e5a55adfca8717ecb973ebb7743849ff956d896a7ed"],"a4a4d6c6034da8aa06f01fe71f1fffbd79e032006b07f6c7a2c60a66aa310c01","0385acb4f0fe889ef0","3588f34fbbc11640f9ed40b2a66a4e096215d50389691309c1dac74d4268aa81","Includes witness data"]
]
diff --git a/bip-0173.mediawiki b/bip-0173.mediawiki
index c2178b5..c99b6c6 100644
--- a/bip-0173.mediawiki
+++ b/bip-0173.mediawiki
@@ -6,7 +6,7 @@
Greg Maxwell <greg@xiph.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0173
- Status: Proposed
+ Status: Final
Type: Informational
Created: 2017-03-20
License: BSD-2-Clause