Sequential spending of notes within the same block

Multiple invocations of simple-spend within the same block height - which use the same source note/s - will produce identical draft ids.

Therefore, even if not overspending the source note/s, all but the most recent send-tx will fail.

I understand that this an intended consequence of the UXTO model and that only the most recent txn id will be processed.

Is it therefore necessary to make multiple transactions (which use the balance of the same source note/s) in a single simple-spend - until at least the first spend is included in the chain - and the address’s notes are updated?

Is the wallet capable of generating updated notes (with any pending spend applied), before the block containing the first txn is minted, so that sequential spends can be made within the same block height?

1 Like

Yes, you can multi send like:

nockchain-wallet spend \
  --names "[first last],[first last]" \
  --recipients "[1 RECEIVER],[1 RECEIVER]" \
  --gifts "100,200" \
  --fee 10
2 Likes

This is fine if a wallet operator plans out every transaction that they want to make within the following ~10 mins, but my question was more about doing sequential spends, i.e. a series of simple-spends from the same note/s, during the same block height - which was failing - perhaps because of the duplicate draft id issue which I mentioned.

I ran a test with spend just now, and it seems the duplicate .draft id issue is no longer relevant, since sequential spend calls will generate new .tx ids each time

However, sequential spending within the same block still fails:

heard-tx: Inputs present in spent-by, discarding transaction

1 Like

Here are my logs:

transaction #1

āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock list-notes-by-pubkey "3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw"
I (13:35:23) [no] kernel::boot: Tracy tracing is enabled
I (13:35:23) [no] kernel::boot: kernel: starting
I (13:35:26) [%build-hash 0v10.5g71s]
I (13:35:26) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
Wallet Notes for Public Key '3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw'
\0a
Details
- Name: [B15hYHaErRmHywcuigw6NUfRUiDGaBpjTQmB7kHWv5LixRh16BaaqoN 5mSj9nmKKjsJJXt4dc9ZzT1uXaAzXay2RwgKeCq52VAFJK8gebUSjDy]
- Assets: 26426793
- Block Height: 20362
- Source: AKRU4dhhkQD7KHfgP8LgmdQ45Zz7sXDDvDQVPkqSE1Wf7WWmNkzojPR
Lock
- Required Signatures: 1
- Signers: 3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw

I (13:35:38) nockchain_wallet: Command executed successfully


āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock \
  spend \
  --names "[B15hYHaErRmHywcuigw6NUfRUiDGaBpjTQmB7kHWv5LixRh16BaaqoN 5mSj9nmKKjsJJXt4dc9ZzT1uXaAzXay2RwgKeCq52VAFJK8gebUSjDy]" \
  --recipients "[1 3MyUmQ6GNQACWwQNHP9VTdi6QmeT2nNci22KnVRVeXbeEY1UZ2UyRyzVCQDmxn5d1onHCiYddcqKiZSMWLrLCB9RJZR7phcbCHwQ32CppvpPNVU1c4iSXQvpVF5j1Ri4FbxW]" \
  --gifts 65536 \
  --fee 1
I (13:35:57) [no] kernel::boot: Tracy tracing is enabled
I (13:35:57) [no] kernel::boot: kernel: starting
I (13:36:00) [%build-hash 0v10.5g71s]
I (13:36:00) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
I (13:36:01) "Validating transaction before saving"
Transaction
Name: 22Y9cceafmmyRT9nT66ue4YtQvF5UQFuAhxuMpd2t2Zwys3fBUkprR2
Inputs:

- Assets: 26361256
  - Nocks: 402
  - Nicks: 15784
- Required Signatures: 1
- Signers: 3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw

- Assets: 65536
  - Nocks: 1
  - Nicks: 0
- Required Signatures: 1
- Signers: 3MyUmQ6GNQACWwQNHP9VTdi6QmeT2nNci22KnVRVeXbeEY1UZ2UyRyzVCQDmxn5d1onHCiYddcqKiZSMWLrLCB9RJZR7phcbCHwQ32CppvpPNVU1c4iSXQvpVF5j1Ri4FbxW

I (13:36:02) nockchain_wallet: Command executed successfully


āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock sign-tx txs/22Y9cceafmmyRT9nT66ue4YtQvF5UQFuAhxuMpd2t2Zwys3fBUkprR2.tx
I (13:36:14) [no] kernel::boot: Tracy tracing is enabled
I (13:36:14) [no] kernel::boot: kernel: starting
I (13:36:17) [%build-hash 0v10.5g71s]
I (13:36:17) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
I (13:36:19) nockchain_wallet: Command executed successfully


āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock send-tx txs/22Y9cceafmmyRT9nT66ue4YtQvF5UQFuAhxuMpd2t2Zwys3fBUkprR2.tx
I (13:36:24) [no] kernel::boot: Tracy tracing is enabled
I (13:36:24) [no] kernel::boot: kernel: starting
I (13:36:27) [%build-hash 0v10.5g71s]
I (13:36:27) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
I (13:36:38) nockchain_wallet: Command executed successfully

transaction #2:

āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock list-notes-by-pubkey "3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw"
I (13:36:41) [no] kernel::boot: Tracy tracing is enabled
I (13:36:41) [no] kernel::boot: kernel: starting
I (13:36:44) [%build-hash 0v10.5g71s]
I (13:36:44) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
Wallet Notes for Public Key '3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw'
\0a
Details
- Name: [B15hYHaErRmHywcuigw6NUfRUiDGaBpjTQmB7kHWv5LixRh16BaaqoN 5mSj9nmKKjsJJXt4dc9ZzT1uXaAzXay2RwgKeCq52VAFJK8gebUSjDy]
- Assets: 26426793
- Block Height: 20362
- Source: AKRU4dhhkQD7KHfgP8LgmdQ45Zz7sXDDvDQVPkqSE1Wf7WWmNkzojPR
Lock
- Required Signatures: 1
- Signers: 3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw

I (13:36:55) nockchain_wallet: Command executed successfully


āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock \
  spend \
  --names "[B15hYHaErRmHywcuigw6NUfRUiDGaBpjTQmB7kHWv5LixRh16BaaqoN 5mSj9nmKKjsJJXt4dc9ZzT1uXaAzXay2RwgKeCq52VAFJK8gebUSjDy]" \
  --recipients "[1 3kA3NZB8ZQSTSE7kBBMF7bWYtjJsoCCQsJtM9aJyNT5vdLSBFNymsPXsrZpEi3foxQJTbeEVgyLemhUeEAZM5FDmx2d6GoqCR8jfHxiyvwaeuk6912vidw7iDNhfc5fRM3MK]" \
  --gifts 65536 \
  --fee 1
I (13:37:09) [no] kernel::boot: Tracy tracing is enabled
I (13:37:09) [no] kernel::boot: kernel: starting
I (13:37:12) [%build-hash 0v10.5g71s]
I (13:37:12) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
I (13:37:12) "Validating transaction before saving"
Transaction
Name: 2N1aTi3ZjN8ECL2ejduHzLM9skL6NEffKPGd54h9QPdDiKYyCoim1Ug
Inputs:

- Assets: 26361256
  - Nocks: 402
  - Nicks: 15784
- Required Signatures: 1
- Signers: 3rFbFHkS8YpcjBbyaJUVAx8GZpS6AFhyFQv1s9YdTzri5jtL3m9AjfP5TK8egkrAQptxajCJuWFqN4qQuhznGgaZMrsVirfEHmdRkpH4KbGba925rmYfqAVbJBzNtcbqKWMw

- Assets: 65536
  - Nocks: 1
  - Nicks: 0
- Required Signatures: 1
- Signers: 3kA3NZB8ZQSTSE7kBBMF7bWYtjJsoCCQsJtM9aJyNT5vdLSBFNymsPXsrZpEi3foxQJTbeEVgyLemhUeEAZM5FDmx2d6GoqCR8jfHxiyvwaeuk6912vidw7iDNhfc5fRM3MK

I (13:37:13) nockchain_wallet: Command executed successfully


āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock sign-tx txs/2N1aTi3ZjN8ECL2ejduHzLM9skL6NEffKPGd54h9QPdDiKYyCoim1Ug.tx
I (13:37:20) [no] kernel::boot: Tracy tracing is enabled
I (13:37:20) [no] kernel::boot: kernel: starting
I (13:37:22) [%build-hash 0v10.5g71s]
I (13:37:23) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
I (13:37:24) nockchain_wallet: Command executed successfully


āÆ nockchain-wallet --nockchain-socket .socket/nockchain_npc.sock send-tx txs/2N1aTi3ZjN8ECL2ejduHzLM9skL6NEffKPGd54h9QPdDiKYyCoim1Ug.tx
I (13:37:29) [no] kernel::boot: Tracy tracing is enabled
I (13:37:29) [no] kernel::boot: kernel: starting
I (13:37:32) [%build-hash 0v10.5g71s]
I (13:37:32) nockchain_wallet: Connected to nockchain NPC socket at ".socket/nockchain_npc.sock"
I (13:37:42) nockchain_wallet: Command executed successfully

nockchain (concurrent):

I (13:34:30) accept-block: block CiCd5xJ9Fk6qPRYcUjdZJ5e4wvbPS5WeRdSiFoZTu1ENn4tY6pFNW7w added to validated blocks at 20362 with proof version 2
I (13:34:30) update-heaviest: Checking if block CiCd5xJ9Fk6qPRYcUjdZJ5e4wvbPS5WeRdSiFoZTu1ENn4tY6pFNW7w is heaviest
I (13:34:30) update-heaviest: Block CiCd5xJ9Fk6qPRYcUjdZJ5e4wvbPS5WeRdSiFoZTu1ENn4tY6pFNW7w is new heaviest block
I (13:34:30) accept-block: New heaviest block!
I (13:34:30) heard-new-block: Generating new candidate block with parent: CiCd5xJ9Fk6qPRYcUjdZJ5e4wvbPS5WeRdSiFoZTu1ENn4tY6pFNW7w
I (13:34:31) handle-fact: heard-block
W (13:34:31) heard-block: Duplicate block
I (13:34:31) handle-fact: heard-tx
I (13:34:31) heard-tx: Received raw transaction
I (13:34:31) heard-tx: Raw transaction id: 5e3oWv6tZeiopFeZpPyGrPn8jrX7ZHp26sRyWHPe31cHVmpeXm8yhZB
W (13:34:31) heard-tx: Transaction id already seen: 5e3oWv6tZeiopFeZpPyGrPn8jrX7ZHp26sRyWHPe31cHVmpeXm8yhZB
I (13:34:39) handle-command: timer
I (13:34:46) p2p_state: Removing peer: 12D3KooWCqfv87cXb6LtF2ug5d9QfaVePrj5yEDcptVCvgcdN6ma
I (13:34:59) handle-command: timer
I (13:35:19) handle-command: timer
I (13:35:39) handle-command: timer
I (13:35:59) handle-command: timer
I (13:36:19) handle-command: timer

I (13:36:37) handle-fact: heard-tx
I (13:36:37) heard-tx: Received raw transaction
I (13:36:37) heard-tx: Raw transaction id: 22Y9cceafmmyRT9nT66ue4YtQvF5UQFuAhxuMpd2t2Zwys3fBUkprR2
I (13:36:37) heard-tx: Heard new valid transaction

I (13:36:42) handle-command: timer
E (13:36:42) [no] drivers::npc: npc: client task error: IoError(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" })
I (13:36:59) handle-command: timer
I (13:37:19) driver: Logging current peer status...
I (13:37:19) driver: Current peer status connected_peers=4 peers=["12D3KooWCCWmFsRfGn8K8smzK2xxkWG4wVwUj2LfK8h5WnvturDV", "12D3KooWQnmCSfcLpJoSi5SZguckY3qYrMkCPAXr2GjGUsHrVa7r", "12D3KooWAqwApb5Aad6A7NdJvSThM8Ngat8qWnBmWC6uippVgWt7", "12D3KooWMnKBBWwtf4e1AaeoB2W6zrVgA1XRwucQNkL7CpFR1HWo"]
I (13:37:19) driver: Routing table has 5 entries routing_table_size=5
I (13:37:19) driver: Redialing /dnsaddr/nockchain-backbone.zorp.io/p2p/12D3KooWCqfv87cXb6LtF2ug5d9QfaVePrj5yEDcptVCvgcdN6ma
I (13:37:19) handle-command: timer
I (13:37:19) driver: Redialing /ip4/34.174.118.156/udp/33000/quic-v1/p2p/12D3KooWCqfv87cXb6LtF2ug5d9QfaVePrj5yEDcptVCvgcdN6ma
W (13:37:21) driver: Wrong peer id 12D3KooWRLba5VxMeESWcvoe6VfRHqfNiwWfg4fdrUoeay1H1rgv from address /ip4/38.134.40.49/udp/3006/quic-v1/p2p/12D3KooWEXNWfGZNtsbrzhfi3vDZUYG2LQdFEHVL7XXP1gUxQWQu
I (13:37:39) handle-command: timer

I (13:37:41) handle-fact: heard-tx
I (13:37:41) heard-tx: Received raw transaction
I (13:37:41) heard-tx: Raw transaction id: 2N1aTi3ZjN8ECL2ejduHzLM9skL6NEffKPGd54h9QPdDiKYyCoim1Ug
W (13:37:41) heard-tx: Inputs present in spent-by, discarding transaction

W (13:37:47) driver: Wrong peer id 12D3KooWDtZ6xLvMvKaULSpKYrUc4NQiH3vdo1ejHxGBTpjLyU1K from address /ip4/15.204.164.29/udp/3006/quic-v1/p2p/12D3KooWNhdGqKkk8SRVXsY3yGk6LCer69p7NwzL7N5tx3Bqgk2S
I (13:37:59) handle-command: timer

Expectation: Both 22Y9cceafmmyRT9nT66ue4YtQvF5UQFuAhxuMpd2t2Zwys3fBUkprR2 AND 2N1aTi3ZjN8ECL2ejduHzLM9skL6NEffKPGd54h9QPdDiKYyCoim1Ug should be received.

Outcome: Only the first txn 22Y9cceafmmyRT9nT66ue4YtQvF5UQFuAhxuMpd2t2Zwys3fBUkprR2 is received.

1 Like

I think what is happening here is you are essentially trying to double spend. Your second transaction needs to spent the outputs of the first transaction. Even tho you didn’t spend all the note, the entire note is used because you get it back as change in a new note. You need to spend the change note on second txn.

Sure, that makes sense. However, is it possible to retrieve this ā€˜change’ note - whilst at the same block height that txn1 was made in?

In my test, I performed a fresh list-notes-by-pubkey after the first txn - but the returned note is identical. My guess is; no - this is an intrinsic limitation of the UTXO model.

I’m curious if it is feasible for wallet software to preemptively create a ā€˜change’ note however - before the current block is minted…

…otherwise, my conclusion is that it is impossible to make sequential spends during a single block height - outside of the following case:

(a) The wallet happens to have multiple notes
AND
(b) each transaction’s gift amount does not exceed the balance of it’s corresponding note/s.

1 Like

I’m not familiar enough with how the note names are produced (assuming some sort of hash with block number) but I suspect you are correct in assuming this is not possible. Even if you were to calculate the change note you would need to ensure the first txn executes first which is not possible without some sort of ordering.

I think the workaround is to batch up the txns in a multisend and send them each block. After each block, update your current batch with new notes. So the wallet tracks its own unsettled state and updates each block.

Maybe one of the devs can weigh in on how the note names are calculated.

2 Likes

I don’t know if this applies, but there is a more advanced spend at the seed level although it is not implemented in the simple-spend aka spend command of cli wallet.

https://x.com/i/grok/share/Ryltzseb848uVMmd2qcvj2ZEn

1 Like

Queueing the spends across future blocks seems like the right solve, and maybe GitHub - SWPSCO/aeroe: Premier wallet and mining client for Nockchain has covered this use case already…

But even with a GUI wallet, it would still need to prevent the user from closing the application, until all queued transactions are sent - which doesn’t seem right to me. Maybe I’m missing something more fundamental here :sweat_smile: