3

I am kind of confused with something. I hope you can clarify it for me...

Let's say I want to make a transaction. So my exchange wallet does that for me. The way it does this is it first grabs the UTXO list (let's say it has that on disk D), grabs those that can be used, and using those UTXO creates a transaction with the valid inputs. Then, this transaction goes to the node's mempool. Then, when starting to mine a block, the node grabs those transactions, puts them in a block and mining starts.

Question 1) when will the UTXO list be updated on disk D? Before putting a transaction into a mempool, or after a miner solves a block or maybe at that time when the miner grabs transactions from the mempool?

If the answer is: before putting a transaction into a mempool, then, things get complicated because if that node doesn't solve the block, there's a chance that updating UTXO shouldn't have happened, so it means that the node will revert the utxo back to what it was.

If the answer is: after a miner solves a block, then it's possible that my node will let me do the same transaction twice, since before creating a transaction, it checks UTXO list.

If the answer is: when a miner grabs transactions from mempool, then this is pretty wrong, since mempool already contains validated transactions.

What do you think?

UPDATE QUESTION:

Let's say I have 1 BTC and published 1BTC transaction to Bob on nodeA and the same 1BTC transaction to Alice on nodeB.

So, let's say transaction broadcasting didn't happen, so they(nodeA, nodeB) don't know each other's transaction.

Now, nodeA mined a block first and broadcasted the block. nodeB received this block. Now, nodeB uses lots of different UTXO's as you stated. One check that gets done is nodeB loops through the nodeA's block's transactions and if any of the transaction can be found(compares transaction id's) in its mempool, it removes it. Now, How will nodeB remove the transaction to Alice(which is now a double spend) ? How does it come to this conclusion ?

7

This is implementation dependent, but in Bitcoin Core there is not just a single UTXO set:

  1. The UTXO set on disk in the chainstate/ directory in a database. It corresponds to the state as of the last flushed block (and does not include the effects of any mempool transaction, or of any block since the last flush).
  2. The in-memory coins cache is a cache on top of the UTXO set on disk (1), with spends/creations from recent unflushed blocks applied. It only physically stores the changed values; querying it for other UTXOs will cause a read from the disk database (1) instead.
  3. The mempool implicitly defines yet another UTXO set on top of (2). This isn't materialized at all: when querying, we just check if either (2) or the mempool has the transaction output asked for AND whether there is no mempool transaction that spends it. The mempool is always kept consistent with the blockchain (e.g. if a transaction is confirmed that conflicts with a mempool transaction, that mempool transaction is deleted).
  4. During processing of a block, a temporary cache of UTXO changes is maintained, as a patch on top of (2). This allows blocks to spend outputs created by themselves, while if a block is invalid for whatever reason, that temporary cache can just be thrown out without doing extra work. Only if the block is actually completely valid are the changes from this temporary cache merged into (2), and the mempool (3) updated to be consistent with the result.
  5. Wallets conceptually also maintain their own set of UTXOs (that are watched and/or spendable by the owner), though they don't use the same interface in the codebase. This is necessary because a wallet may contain transactions that are unconfirmed and aren't in the mempool (e.g. because they were removed due to eviction, but we still want to retry inserting them).

Finally it's important to note that every node has its own UTXO set(s). Your own wallet/node won't be updating anything when a miner (which one?) starts including your transaction in their candidate blocks - you don't even have any way of knowing they're doing so.

| improve this answer | |
  • 2
    I believe I answered that in point 3: the mempool is always kept consistent with the accepted best block. When nodeB receives nodeA's block, it gets accepted as best block. Whatever is in nodeB's mempool that conflicts with that new block will be thrown out. – Pieter Wuille Nov 5 at 20:00
  • 2
    There are no balances in Bitcoin. UTXOs are created once and spent once in their entirety. Any mempool transaction that spends a UTXO that no longer exists after a block was received will be deleted from the mempool. – Pieter Wuille Nov 5 at 20:06
  • 2
    You're missing the point. The numbers don't matter. There are no balances, there are UTXOs. If tx T had one output, regardless of its amount, that output can be spent once. If it had two outputs, each of those outputs can be spent once - possibly in distinct transactions or even distinct blocks. A transaction conflicts with another transaction if they directly or indirectly spend the same output. – Pieter Wuille Nov 5 at 20:10
  • 2
    It depends on whether those 2 BTC were in one or multiple outputs. If there was only one output, then a transaction moving 1 BTC to alice would be spending the 2 BTC output, and creating 1 BTC output assigned to alice and another 1 BTC output back to the sender. When that transaction is confirmed, the 2 BTC does not exist anymore, and nothing else can spend it. A new transaction would need to spend the 1 BTC change output instead. If there were two 1 BTC outputs to start with, and transactions spending each, then those transactions wouldn't necessarily conflict. – Pieter Wuille Nov 5 at 20:15
  • 2
    Well, the genesis block has no outputs (intentionally or due to an oversight in the original codebase). Ignoring that, if you have a single UTXO of 50 BTC, yes you can construct two transactions that can end up in the same block. A first one would spend the 50 BTC and create say a 10 BTC and 40 BTC output to yourself. Another transaction would then spend the 40 BTC output and create say a 5 BTC output and a 35 BTC output. These two transactions can legally appear in the same block, and the net effect is splitting 50 BTC into 10 BTC + 5 BTC + 35 BTC. – Pieter Wuille Nov 5 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.