mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-11-15 12:39:01 +00:00
CH10: s/(SPV|lightweight) node/\1 client/
This commit is contained in:
parent
28cfc751c1
commit
f1aea5e372
104
ch08.asciidoc
104
ch08.asciidoc
@ -527,23 +527,21 @@ an extended period of time.
|
||||
[[spv_nodes]]
|
||||
=== Simplified Payment Verification (SPV) Nodes
|
||||
|
||||
((("bitcoin network", "SPV nodes", id="BNspvnodes08")))((("bitcoin
|
||||
nodes", "SPV nodes", id="BNospv08")))((("simple-payment-verification
|
||||
(SPV)", id="simple08")))Not all nodes have the ability to store the full
|
||||
blockchain. Many Bitcoin clients are designed to run on space- and
|
||||
((("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
|
||||
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 storing the full
|
||||
method is used to allow them to operate without validating the full
|
||||
blockchain. These types of clients are called SPV clients or lightweight
|
||||
clients. As Bitcoin adoption surges, the SPV node is becoming the most
|
||||
common form of Bitcoin node, especially for Bitcoin wallets.
|
||||
clients.
|
||||
|
||||
SPV nodes download only the block headers and do not download the
|
||||
SPV clients download only the block headers and do not download the
|
||||
transactions included in each block. The resulting chain of blocks,
|
||||
without transactions, is 1,000 times smaller than the full blockchain.
|
||||
SPV nodes cannot construct a full picture of all the UTXOs that are
|
||||
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
|
||||
available for spending because they do not know about all the
|
||||
transactions on the network. SPV nodes verify transactions using a
|
||||
transactions on the network. SPV clients verify transactions using a
|
||||
slightly different method that relies on peers to provide partial views
|
||||
of relevant parts of the blockchain on demand.
|
||||
|
||||
@ -567,7 +565,7 @@ database of UTXO, establishing the validity of the transaction by
|
||||
confirming that the UTXO remains unspent. An SPV node cannot validate
|
||||
whether the UTXO is unspent. Instead, the SPV node will establish a link
|
||||
between the transaction and the block that contains it, using a _merkle
|
||||
path_ (see <<merkle_trees>>). Then, the SPV node waits until it sees the
|
||||
path_ (see <<merkle_trees>>). Then, the SPV client waits until it sees the
|
||||
six blocks 300,001 through 300,006 piled on top of the block containing
|
||||
the transaction and verifies it by establishing its depth under blocks
|
||||
300,006 to 300,001. The fact that other nodes on the network accepted
|
||||
@ -575,24 +573,24 @@ block 300,000 and then did the necessary work to produce six more blocks
|
||||
on top of it is proof, by proxy, that the transaction was not a
|
||||
double-spend.
|
||||
|
||||
An SPV node cannot be persuaded that a transaction exists in a block
|
||||
when the transaction does not in fact exist. The SPV node establishes
|
||||
An SPV client cannot be persuaded that a transaction exists in a block
|
||||
when the transaction does not in fact exist. The SPV 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 node. An
|
||||
SPV node can definitely prove that a transaction exists but cannot
|
||||
However, a transaction's existence can be "hidden" from an SPV client. An
|
||||
SPV 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 nodes. To defend against this, an SPV
|
||||
node needs to connect randomly to several nodes, to increase the
|
||||
double-spending attack against SPV clients. To defend against this, an SPV
|
||||
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 nodes also are vulnerable to
|
||||
need to randomly connect means that SPV 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 most practical purposes, well-connected SPV nodes are secure enough,
|
||||
For most practical purposes, well-connected SPV clients are secure enough,
|
||||
striking a balance between resource needs, practicality, and security.
|
||||
For infallible security, however, nothing beats running a full
|
||||
blockchain node.
|
||||
@ -601,36 +599,36 @@ blockchain node.
|
||||
====
|
||||
A full blockchain node verifies a transaction by checking the entire
|
||||
chain of thousands of blocks below it in order to guarantee that the
|
||||
UTXO is not spent, whereas an SPV node checks how deep the block is
|
||||
UTXO is not spent, whereas an SPV client checks how deep the block is
|
||||
buried by a handful of blocks above it.
|
||||
====
|
||||
|
||||
To get the block headers, SPV nodes use a +getheaders+ message instead
|
||||
To get the block headers, SPV clients use a +getheaders+ message instead
|
||||
of +getblocks+. The responding peer will send up to 2,000 block headers
|
||||
using a single +headers+ message. The process is otherwise the same as
|
||||
that used by a full node to retrieve full blocks. SPV nodes also set a
|
||||
that used by a full node to retrieve full blocks. SPV clients also set a
|
||||
filter on the connection to peers, to filter the stream of future blocks
|
||||
and transactions sent by the peers. Any transactions of interest are
|
||||
retrieved using a +getdata+ request. The peer generates a +tx+ message
|
||||
containing the transactions, in response. <<spv_synchronization>> shows
|
||||
the synchronization of block headers.
|
||||
|
||||
Because SPV nodes need to retrieve specific transactions in order to
|
||||
Because SPV clients need to retrieve specific transactions in order to
|
||||
selectively verify them, they also create a privacy risk. Unlike full
|
||||
blockchain nodes, which collect all transactions within each block, the
|
||||
SPV node's requests for specific data can inadvertently reveal the
|
||||
SPV client's requests for specific data can inadvertently reveal the
|
||||
addresses in their wallet. For example, a third party monitoring a
|
||||
network could keep track of all the transactions requested by a wallet
|
||||
on an SPV node and use those to associate Bitcoin addresses with the
|
||||
on an SPV client and use those to associate Bitcoin addresses with the
|
||||
user of that wallet, destroying the user's privacy.
|
||||
|
||||
[[spv_synchronization]]
|
||||
.SPV node synchronizing the block headers
|
||||
.SPV client synchronizing the block headers
|
||||
image::images/mbc2_0807.png["SPVSynchronization"]
|
||||
|
||||
Shortly after the introduction of SPV/lightweight nodes, Bitcoin
|
||||
Shortly after the introduction of SPV/lightweight clients, Bitcoin
|
||||
developers added a feature called _bloom filters_ to address the privacy
|
||||
risks of SPV nodes. Bloom filters allow SPV nodes to receive a subset of
|
||||
risks of SPV clients. Bloom filters allow SPV clients to receive a subset of
|
||||
the transactions without revealing precisely which addresses they are
|
||||
interested in, through a filtering mechanism that uses probabilities
|
||||
rather than fixed patterns.((("", startref="BNspvnodes08")))((("",
|
||||
@ -645,7 +643,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 nodes to ask their peers for
|
||||
protecting privacy. They are used by SPV clients to ask their peers for
|
||||
transactions matching a specific pattern, without revealing exactly
|
||||
which addresses, keys, or transactions they are searching for.
|
||||
|
||||
@ -664,13 +662,13 @@ 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 node to specify a
|
||||
Bloom filters serve this function by allowing an SPV 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 node is interested in,
|
||||
at the expense of revealing what patterns the SPV 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 node, but will allow the node to maintain better
|
||||
irrelevant to the client, but will allow the client to maintain better
|
||||
privacy.
|
||||
|
||||
==== How Bloom Filters Work
|
||||
@ -679,7 +677,7 @@ Bloom filters are implemented as a variable-size array of N binary
|
||||
digits (a bit field) and a variable number of M hash functions. The hash
|
||||
functions are designed to always produce an output that is between 1 and
|
||||
N, corresponding to the array of binary digits. The hash functions are
|
||||
generated deterministically, so that any node implementing a bloom
|
||||
generated deterministically, so that any client implementing a bloom
|
||||
filter will always use the same hash functions and get the same results
|
||||
for a specific input. By choosing different length (N) bloom filters and
|
||||
a different number (M) of hash functions, the bloom filter can be tuned,
|
||||
@ -761,23 +759,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 Nodes Use Bloom Filters
|
||||
=== How SPV clients Use Bloom Filters
|
||||
|
||||
Bloom filters are used to filter the transactions (and blocks containing
|
||||
them) that an SPV node receives from its peers, selecting only
|
||||
transactions of interest to the SPV node without revealing which
|
||||
them) that an SPV client receives from its peers, selecting only
|
||||
transactions of interest to the SPV client without revealing which
|
||||
addresses or keys it is interested in.
|
||||
|
||||
((("transaction IDs (txid)")))An SPV node will initialize a bloom filter
|
||||
((("transaction IDs (txid)")))An SPV client will initialize a bloom filter
|
||||
as "empty"; in that state the bloom filter will not match any patterns.
|
||||
The SPV node will then make a list of all the addresses, keys, and
|
||||
The SPV 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 node then adds each of these to the
|
||||
controlled by its wallet. The SPV 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 node will then send a
|
||||
((("Bitcoin nodes", "full nodes")))The SPV 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
|
||||
@ -795,15 +793,15 @@ script.
|
||||
|
||||
After a filter is established, the peer will then test each
|
||||
transaction's outputs against the bloom filter. Only transactions that
|
||||
match the filter are sent to the node.
|
||||
match the filter are sent to the client.
|
||||
|
||||
In response to a +getdata+ message from the node, peers will send a
|
||||
In response to a +getdata+ message from the client, peers will send a
|
||||
+merkleblock+ message that contains only block headers for blocks
|
||||
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 node, the SPV node
|
||||
As the full node sends transactions to the SPV client, the SPV 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
|
||||
@ -811,26 +809,26 @@ transactions referencing the UTXO it just found. The full node then uses
|
||||
the new bloom filter to match new transactions and the whole process
|
||||
repeats.
|
||||
|
||||
The node setting the bloom filter can interactively add patterns to the
|
||||
The client setting the bloom filter can interactively add patterns to the
|
||||
filter by sending a +filteradd+ message. To clear the bloom filter, the
|
||||
node can send a +filterclear+ message. Because it is not possible to
|
||||
remove a pattern from a bloom filter, a node has to clear and resend a
|
||||
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 nodes is defined
|
||||
The network protocol and bloom filter mechanism for SPV clients is defined
|
||||
in http://bit.ly/1x6qCiO[BIP-37 (Peer Services)].((("",
|
||||
startref="BNebloom08")))((("", startref="bloom08")))
|
||||
|
||||
=== SPV Nodes and Privacy
|
||||
=== SPV Clients and Privacy
|
||||
|
||||
Nodes that implement SPV have weaker privacy than a full node. A full
|
||||
Clients that implement SPV have weaker privacy than a full node. A full
|
||||
node receives all transactions and therefore reveals no information
|
||||
about whether it is using some address in its wallet. An SPV node
|
||||
about whether it is using some address in its wallet. An SPV client
|
||||
receives a filtered list of transactions related to the addresses that
|
||||
are in its wallet. As a result, it reduces the privacy of the owner.
|
||||
|
||||
Bloom filters are a way to reduce the loss of privacy. Without them, an
|
||||
SPV node would have to explicitly list the addresses it was interested
|
||||
SPV client would have to explicitly list the addresses it was interested
|
||||
in, creating a serious breach of privacy. However, even with bloom
|
||||
filters, an adversary monitoring the traffic of an SPV client or
|
||||
connected to it directly as a node in the P2P network can collect enough
|
||||
@ -844,7 +842,7 @@ connections")))((("encryption")))((("authentication")))Most new users of
|
||||
Bitcoin assume that the network communications of a Bitcoin node are
|
||||
encrypted. In fact, the original implementation of bitcoin communicates
|
||||
entirely in the clear. While this is not a major privacy concern for
|
||||
full nodes, it is a big problem for SPV nodes.
|
||||
full nodes, it is a big problem for SPV clients.
|
||||
|
||||
As a way to increase the privacy and security of the Bitcoin P2P
|
||||
network, there are two solutions that provide encryption of the
|
||||
|
Loading…
Reference in New Issue
Block a user