Repository navigation
Conversation
…r mined addTransaction now refuses a transaction whose id is already waiting in the pending list or stored in any block, so an authorised payment can be applied only once. isValid() also fails a chain in which the same transaction id appears more than once. Adds regression tests for the pending duplicate, the replay of a mined transaction and a hand-mined block that repeats an id. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
They only exercise addTransaction and isValid, so they do not need to share BlockchainTest.java, which keeps this change from touching a file other changes append to.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #16
What I changed
Blockchain.addTransactionnow rejects a transaction whose id is already in the pending list or in any mined block ("Transaction was already submitted."). The check runs right after the signature check, before the sender's key is registered.Blockchain.isValidnow returns false if the same transaction id appears more than once across the mined blocks.ReplayTest.java: a pending transaction can't be added twice; a transaction copied out of a mined block can't be submitted again (balances stay 20 / 80 and the chain stays valid); a properly mined block that repeats a transaction id makesisValid()false.Only
Blockchain.javaand the newReplayTest.javachange.How it works
Every transaction already has a unique id, but the chain never checked whether it had seen that id before, so one payment Asha signed once could be copied out of a block and submitted again, and each copy was charged to her. Now
addTransactionlooks for the id in the pending list and in every block and refuses it if it is found, so a signed payment moves coins once.isValiddoes the same check while walking the chain (a set of ids seen so far), so a chain that contains a repeated id is reported as invalid and is not saved.Existing
chain.datfiles: if a saved chain already contains a replayed transaction (the same id twice),isValid()is now false for it, soStorage.loadwill print "doesn't hold a valid chain" and start a new chain instead of loading it. That is the intended behaviour for a chain that was already double-spent, but it means such a file is no longer loadable. Files without repeated ids are unaffected, and no saved format or serialVersionUID changes. Duplicates inside a saved pending list are not checked byisValid(it only looks at mined blocks, as before).How I tested it
main(pendingTransactionCannotBeAddedTwiceandminedTransactionCannotBeReplayedexpect an exception that is never thrown,repeatedTransactionIdInvalidatesChainexpects false but gets true) and pass with the change.mvn -B clean test: 21 tests, 0 failures (18 existing + 3 new), JDK 17.