1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-12-26 08:28:15 +00:00

All: mostly replace "SPV client" with "lightweight client"

The description of SPV in the original paper assumed full nodes would
warn SPV clients about invalid blocks.  Such fraud proofs are not used
in production, so lightweight clients are (arguably) not SPV clients.
This commit is contained in:
David A. Harding 2023-08-06 20:53:22 -10:00
parent 672c3fdc07
commit b8933271ff
7 changed files with 66 additions and 71 deletions

View File

@ -12,7 +12,7 @@ _Process_ BIP:: Describes a bitcoin process, or proposes a change to (or an even
((("bitcoin improvement proposals", "repository of")))BIPs are recorded in a versioned repository on GitHub: https://github.com/bitcoin/bips[https://github.com/bitcoin/bips].
An MIT-licensed document from the open source Bitcoin Core project,
reproduced here, describes which BIPs it implements, including listing
reproduced here in edited form, describes which BIPs it implements, including listing
the version of Bitcoin Core where support for each BIP was added or
significantly changed.
@ -31,7 +31,7 @@ BIPs that are implemented by Bitcoin Core:
- BIP32: Hierarchical Deterministic Wallets has been implemented since v0.13.0 (PR #8035).
- BIP34: The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since v0.7.0. The rule took effect for version 2 blocks as of block 224413 (March 5th 2013), and version 1 blocks are no longer allowed since block 227931 (March 25th 2013) (PR #1526).
- BIP35: The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since v0.7.0 (PR #1641). As of v0.13.0, this is only available for NODE_BLOOM (BIP111) peers.
- BIP37: The bloom filtering for transaction relaying, partial Merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since v0.8.0 (PR #1795). Disabled by default since v0.19.0, can be enabled by the -peerbloomfilters option.
- BIP37: The bloom filtering for transaction relaying, partial Merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth lightweight clients) has been implemented since v0.8.0 (PR #1795). Disabled by default since v0.19.0, can be enabled by the -peerbloomfilters option.
- BIP42: The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in v0.9.2 (PR #3842).
- BIP43: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP43. (PR #16528)
- BIP44: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP44. (PR #16528)

View File

@ -216,7 +216,7 @@ video for each day of Bitcoin transactions--but the full node offers
complete autonomy to its users.
Lightweight client:: ((("lightweight
clients")))((("simplified-payment-verification (SPV)")))A lightweight
clients")))
client, also known as a simplified-payment-verification (SPV) client,
connects to a full node or other remote server for receiving and sending
Bitcoin transaction information, but stores the user wallet locally,

View File

@ -659,8 +659,7 @@ image::images/mbc2_0209.png["Alice's transaction included in a block"]
=== Spending the Transaction
((("spending bitcoin", "simple-payment-verification
(SPV)")))((("simple-payment-verification (SPV)")))Now that Alice's
Now that Alice's
transaction has been embedded in the blockchain as part of a block, it
is part of the distributed ledger of Bitcoin and visible to all Bitcoin
applications. Each bitcoin full node can independently verify the

View File

@ -50,11 +50,11 @@ functions, such as routing, mining, and wallet services.
Some nodes, called _archival full nodes_, also maintain a
complete and up-to-date copy of the blockchain. Full nodes can
autonomously and authoritatively verify any transaction without external
reference. ((("simple-payment-verification (SPV)"))) Those nodes can
reference. Those nodes can
serve data to clients that store
only a subset of the blockchain and verify transactions using a method
only a subset of the blockchain and partly verify transactions using a method
called _simplified payment verification_, or SPV. ((("lightweight
clients")))These clients are known as lightweight clients or SPV clients.
clients")))These clients are known as lightweight clients.
((("Bitcoin nodes", "mining nodes")))((("mining and consensus", "mining
nodes")))((("Proof-of-Work algorithm")))((("mining and consensus",
@ -518,29 +518,27 @@ retrieving any missing blocks happens any time a node has been offline for
an extended period of time.
[[spv_nodes]]
=== Simplified Payment Verification (SPV) Nodes
=== Lightweight Clients
((("bitcoin network", "SPV clients", id="BNspvnodes08")))((("bitcoin
nodes", "SPV clients", id="BNospv08")))((("simple-payment-verification
(SPV)", id="simple08")))Many Bitcoin clients are designed to run on space- and
Many Bitcoin clients are designed to run on space- and
power-constrained devices, such as smartphones, tablets, or embedded
systems. For such devices, a _simplified payment verification_ (SPV)
method is used to allow them to operate without validating the full
blockchain. These types of clients are called SPV clients or lightweight
blockchain. These types of clients are called lightweight
clients.
SPV clients download only the block headers and do not download the
Lightweight clients download only the block headers and do not download the
transactions included in each block. The resulting chain of headers,
without transactions, is about 10,000 times smaller than the full blockchain.
SPV clients cannot construct a full picture of all the UTXOs that are
Lightweight clients cannot construct a full picture of all the UTXOs that are
available for spending because they do not know about all the
transactions on the network. SPV clients verify transactions using a
transactions on the network. Instead, they verify transactions using a
slightly different method that relies on peers to provide partial views
of relevant parts of the blockchain on demand.
As an analogy, a full node is like a tourist in a strange city, equipped
with a detailed map of every street and every address. By comparison, an
SPV node is like a tourist in a strange city asking random strangers for
with a detailed map of every street and every address. By comparison, a
lightweight client is like a tourist in a strange city asking random strangers for
turn-by-turn directions while knowing only one main avenue. Although
both tourists can verify the existence of a street by visiting it, the
tourist without a map doesn't know what lies down any of the side
@ -550,39 +548,39 @@ a dozen other "23 Church Street" addresses in the city and whether this
is the right one. The mapless tourist's best chance is to ask enough
people and hope some of them are not trying to mug him.
SPV verifies transactions by reference to their _depth_ in the blockchain. Whereas a full node will construct a fully verified chain of thousands of blocks and millions of transactions reaching down the blockchain (back in time) all the way to the genesis block, an SPV node will verify the proof of work of all blocks (but not whether the blocks and all of their transactions are valid) and link that chain to the transaction of interest.
Lightweight clients verify transactions by reference to their _depth_ in the blockchain. Whereas a full node will construct a fully verified chain of thousands of blocks and millions of transactions reaching down the blockchain (back in time) all the way to the genesis block, a lightweight client will verify the proof of work of all blocks (but not whether the blocks and all of their transactions are valid) and link that chain to the transaction of interest.
For example, when examining a transaction in block 800,000, a full node
verifies all 800,000 blocks down to the genesis block and builds a full
database of UTXOs, establishing the validity of the transaction by
confirming that the transaction exists and its output remains unspent. A SPV client can
confirming that the transaction exists and its output remains unspent. A lightweight client can
only verify that the transaction exists. The client establishes a link
between the transaction and the block that contains it, using a _merkle
path_ (see <<merkle_trees>>). Then, the SPV client waits until it sees the
path_ (see <<merkle_trees>>). Then, the lightweight client waits until it sees the
six blocks 800,001 through 800,006 piled on top of the block containing
the transaction and verifies it by establishing its depth under blocks
800,006 to 800,001. The fact that other nodes on the network accepted
block 800,000 and that miners did the necessary work to produce six more blocks
on top of it is proof, by proxy, that the transaction actually exists.
An SPV client cannot normally be persuaded that a transaction exists in a block
when the transaction does not in fact exist. The SPV client establishes
A lightweight client cannot normally be persuaded that a transaction exists in a block
when the transaction does not in fact exist. The lightweight client establishes
the existence of a transaction in a block by requesting a merkle path
proof and by validating the Proof-of-Work in the chain of blocks.
However, a transaction's existence can be "hidden" from an SPV client. An
SPV client can definitely prove that a transaction exists but cannot
However, a transaction's existence can be "hidden" from a lightweight client. A
lightweight client can definitely prove that a transaction exists but cannot
verify that a transaction, such as a double-spend of the same UTXO,
doesn't exist because it doesn't have a record of all transactions. This
vulnerability can be used in a denial-of-service attack or for a
double-spending attack against SPV clients. To defend against this, an SPV
double-spending attack against lightweight clients. To defend against this, a lightweight
client needs to connect randomly to several clients, to increase the
probability that it is in contact with at least one honest node. This
need to randomly connect means that SPV clients also are vulnerable to
need to randomly connect means that lightweight clients also are vulnerable to
network partitioning attacks or Sybil attacks, where they are connected
to fake nodes or fake networks and do not have access to honest nodes or
the real Bitcoin network.
For many practical purposes, well-connected SPV clients are secure enough,
For many practical purposes, well-connected lightweight clients are secure enough,
striking a balance between resource needs, practicality, and security.
For infallible security, however, nothing beats running a full
node.
@ -591,33 +589,33 @@ node.
====
A full node verifies a transaction by checking the entire chain of
thousands of blocks below it in order to guarantee that the UTXO exists
and is not spent, whereas an SPV client only proves that a transaction
and is not spent, whereas an lightweight client only proves that a transaction
exists and checks that the block containing that transaction is
buried by a handful of blocks above it.
====
To get the block headers it needs to verify a transaction is part of the
chain, SPV clients use a +getheaders+ message.
chain, lightweight clients use a +getheaders+ message.
The responding peer will send up to 2,000 block headers
using a single +headers+ message. See the illustration in
<<spv_synchronization>>.
[[spv_synchronization]]
.SPV client synchronizing the block headers
image::images/mbc2_0807.png["SPVSynchronization"]
.Lightweight client synchronizing the block headers
image::images/mbc2_0807.png["Header synchronization"]
Block headers allow an SPV client to verify that any individual block
Block headers allow a lightweight client to verify that any individual block
belongs to the blockchain with the most proof of work, but they don't
tell the client which blocks contain transactions that are interesting to
its wallet. The client could download every block and check, but that
would use a large fraction of the resources it would take to run a full
node, so developers have looked for other ways to solve the problem.
Shortly after the introduction of SPV/lightweight clients, Bitcoin
Shortly after the introduction of lightweight clients, Bitcoin
developers added a feature called _bloom filters_ in an attempt to
reduce the bandwidth that SPV clients needed to use to learn about their
reduce the bandwidth that lightweight clients needed to use to learn about their
incoming and outgoing transactions.
Bloom filters allow SPV clients to receive a subset of
Bloom filters allow lightweight clients to receive a subset of
the transactions without directly revealing precisely which addresses they are
interested in, through a filtering mechanism that uses probabilities
rather than fixed patterns.((("", startref="BNspvnodes08")))((("",
@ -632,7 +630,7 @@ id="privacy08")))((("security", "maintaining privacy",
id="Sprivacy08")))A bloom filter is a probabilistic search filter, a way
to describe a desired pattern without specifying it exactly. Bloom
filters offer an efficient way to express a search pattern while
protecting privacy. They are used by SPV clients to ask their peers for
protecting privacy. They are used by lightweight clients to ask their peers for
transactions matching a specific pattern, without revealing exactly
which addresses, keys, or transactions they are searching for.
@ -651,10 +649,10 @@ more possible addresses and better privacy, but many of the results are
irrelevant. If she asks for a very specific pattern, she gets fewer
results but loses privacy.
Bloom filters serve this function by allowing an SPV client to specify a
Bloom filters serve this function by allowing a lightweight client to specify a
search pattern for transactions that can be tuned toward precision or
privacy. A more specific bloom filter will produce accurate results, but
at the expense of revealing what patterns the SPV client is interested in,
at the expense of revealing what patterns the lightweight client is interested in,
thus revealing the addresses owned by the user's wallet. A less specific
bloom filter will produce more data about more transactions, many
irrelevant to the client, but will allow the client to maintain better
@ -748,23 +746,23 @@ pattern is definitely not a match.
.Testing the existence of pattern "Y" in the bloom filter. The result is a definitive negative match, meaning "Definitely Not!"
image::images/mbc2_0812.png[]
=== How SPV clients Use Bloom Filters
=== How Lightweight Clients Use Bloom Filters
Bloom filters are used to filter the transactions (and blocks containing
them) that an SPV client receives from its peers, selecting only
transactions of interest to the SPV client without revealing exactly which
them) that a lightweight client receives from its peers, selecting only
transactions of interest to the lightweight client without revealing exactly which
addresses or keys it is interested in.
((("transaction IDs (txid)")))An SPV client will initialize a bloom filter
((("transaction IDs (txid)")))A lightweight client will initialize a bloom filter
as "empty"; in that state the bloom filter will not match any patterns.
The SPV client will then make a list of all the addresses, keys, and
The lightweight client will then make a list of all the addresses, keys, and
hashes that it is interested in. It will do this by extracting the
public key hash and script hash and transaction IDs from any UTXO
controlled by its wallet. The SPV client then adds each of these to the
controlled by its wallet. The lightweight client then adds each of these to the
bloom filter, so that the bloom filter will "match" if these patterns
are present in a transaction, without revealing the patterns themselves.
((("Bitcoin nodes", "full nodes")))The SPV client will then send a
((("Bitcoin nodes", "full nodes")))The lightweight client will then send a
+filterload+ message to the peer, containing the bloom filter to use on
the connection. On the peer, bloom filters are checked against each
incoming transaction. The full node checks several parts of the
@ -790,7 +788,7 @@ matching the filter and a merkle path (see <<merkle_trees>>) for each
matching transaction. The peer will then also send +tx+ messages
containing the transactions matched by the filter.
As the full node sends transactions to the SPV client, the SPV client
As the full node sends transactions to the lightweight client, the lightweight client
discards any false positives and uses the correctly matched transactions
to update its UTXO set and wallet balance. As it updates its own view of
the UTXO set, it also modifies the bloom filter to match any future
@ -804,7 +802,7 @@ client can send a +filterclear+ message. Because it is not possible to
remove a pattern from a bloom filter, a client has to clear and resend a
new bloom filter if a pattern is no longer desired.
The network protocol and bloom filter mechanism for SPV clients is defined
The network protocol and bloom filter mechanism for lightweight clients is defined
in http://bit.ly/1x6qCiO[BIP37 (Peer Services)].((("",
startref="BNebloom08")))((("", startref="bloom08")))
@ -827,7 +825,7 @@ which could lead to denial-of-service attacks.
For both of those reasons, Bitcoin Core eventually limited support for
bloom filters to only clients on IP addresses that were explicitly
allowed by the node operator. This meant that an alternative method for
helping SPV clients find their transactions was needed.
helping lightweight clients find their transactions was needed.
=== Compact Block Filters
@ -858,7 +856,7 @@ block from a different peer, making it harder for full nodes to connect
transactions belonging to a single client across multiple blocks.
This idea for server-generated filters doesn't offer perfect privacy,
it still places some costs on full nodes (and it does require SPV
it still places some costs on full nodes (and it does require lightweight
clients use more bandwidth for the block download), and the filters can
only be used for confirmed transactions (not unconfirmed transactions),
but it is much more private and reliable than BIP37 client-requested
@ -1135,19 +1133,19 @@ lightweight client to download an 80-byte block header, a (usually)
small coinbase transaction, and the filter for that block to receive
strong evidence that the filter was accurate.
=== SPV Clients and Privacy
=== Lightweight Clients and Privacy
Clients that implement SPV have weaker privacy than a full node. A full
Lightweight clients have weaker privacy than a full node. A full
node downloads all transactions and therefore reveals no information
about whether it is using some address in its wallet. An SPV client
about whether it is using some address in its wallet. A lightweight client
only downloads transactions that are related to its wallet in some way.
Bloom filters and compact block filters are a way to reduce the loss of privacy. Without them, an
SPV client would have to explicitly list the addresses it was interested
Bloom filters and compact block filters are a way to reduce the loss of privacy. Without them, a
lightweight client would have to explicitly list the addresses it was interested
in, creating a serious breach of privacy. However, even with
filters, an adversary monitoring the traffic of an SPV client or
filters, an adversary monitoring the traffic of a lightweight client or
connected to it directly as a node in the P2P network may be able to collect enough
information over time to learn the addresses in the wallet of the SPV
information over time to learn the addresses in the wallet of the lightweight
client.
=== Encrypted and Authenticated Connections

View File

@ -494,34 +494,32 @@ With merkle trees, a node can download just the block headers (80
bytes per block) and still be able to identify a transaction's inclusion
in a block by retrieving a small merkle path from a full node, without
storing or transmitting the vast majority of the blockchain.
Clients that do not maintain a full
blockchain, called simplified payment verification (SPV) client, use
merkle paths to verify transactions without downloading full blocks.
Clients that do not fully validate transactions, called lightweight
clients, use merkle paths to verify transactions without downloading
full blocks.
//FIXME: stretch goal to minimize use of "SPV" in the book
=== Merkle Trees and Simplified Payment Verification (SPV)
=== Merkle Trees and Lightweight Clients
((("simple-payment-verification (SPV)")))((("bitcoin nodes", "SPV
clients")))Merkle trees are used extensively by SPV clients. SPV clients don't
Merkle trees are used extensively by lightweight clients. Lightweight clients don't
have all transactions and do not download full blocks, just block
headers. In order to verify that a transaction is included in a block,
without having to download all the transactions in the block, they use
a merkle path.
Consider, for example, an SPV client that is interested in incoming
payments to an address contained in its wallet. The SPV client will
Consider, for example, a lightweight client that is interested in incoming
payments to an address contained in its wallet. The lightweight client will
establish a bloom filter (see <<bloom_filters>>) on its connections to
peers to limit the transactions received to only those containing
addresses of interest. When a peer sees a transaction that matches the
bloom filter, it will send that block using a +merkleblock+ message. The
+merkleblock+ message contains the block header as well as a merkle path
that links the transaction of interest to the merkle root in the block.
The SPV client can use this merkle path to connect the transaction to the
block and verify that the transaction is included in the block. The SPV
The lightweight client can use this merkle path to connect the transaction to the
block and verify that the transaction is included in the block. The lightweight
client also uses the block header to link the block to the rest of the
blockchain. The combination of these two links, between the transaction
and block, and between the block and blockchain, proves that the
transaction is recorded in the blockchain. All in all, the SPV client will
transaction is recorded in the blockchain. All in all, the lightweight client will
have received less than a kilobyte of data for the block header and
merkle path, an amount of data that is more than a thousand times less
than a full block (about 2 megabytes currently).((("",

View File

@ -1087,7 +1087,7 @@ unusual problems in software that's not designed to expect them.
// - UTXO model theory?
// Coin selection
// Change
// Inability for SPV clients to get old UTXOs
// Inability for lightweight clients to get old UTXOs
=== Weight and Vbytes

View File

@ -220,7 +220,7 @@ SHA::
The Secure Hash Algorithm or SHA is a family of cryptographic hash functions published by the National Institute of Standards and Technology (NIST).
Simplified Payment Verification (SPV)::
SPV or simplified payment verification is a method for verifying particular transactions were included in a block without downloading the entire block. The method is used by some lightweight Bitcoin clients.
A method for verifying particular transactions were included in a block without downloading the entire block. The method is used by some lightweight Bitcoin clients.
soft fork::
soft fork or Soft-Forking Change is a temporary fork in the blockchain which commonly occurs when miners using non-upgraded nodes don't follow a new consensus rule their nodes dont know about.