-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Massive Spend Refactor #1989
Massive Spend Refactor #1989
Conversation
What's the impact here for OMNI disbursement if any? |
12b7c4d
to
9374151
Compare
// info!("{id} verifying status of spend number({num:?}): {spend:?} : {status:?}"); | ||
// match status { | ||
// SpendStatus::Utxo => { | ||
// // TODO: with the new spend struct requiring `middle payment` |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note test
This reworks the structure of the Spend and refactors the transaction flow, it shouldn't affect OMNI disbursement |
e4203ee
to
c104e4b
Compare
pub fn is_genesis_spend(spend: &SignedSpend) -> bool { | ||
let bytes = spend.spend.to_bytes_for_signing(); | ||
spend.spend.unique_pubkey == *GENESIS_SPEND_UNIQUE_KEY | ||
&& GENESIS_SPEND_UNIQUE_KEY.verify(&spend.derived_key_sig, bytes) | ||
&& is_genesis_parent_tx(&spend.spend.parent_tx) | ||
&& spend.spend.amount == NanoTokens::from(GENESIS_CASHNOTE_AMOUNT) | ||
&& spend.spend.amount() == NanoTokens::from(GENESIS_CASHNOTE_AMOUNT) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we know the content of the Genesis Spend, maybe also add those values in this test to make sure it's the one and unique genesis? Do we know those values?
&& spend.spend.reason == GENESIS_REASON
&& spend.spend.ancestors == GENESIS_ANCESTORS
&& spend.spend.descendants == GENESIS_DESCENDANTS
Assuming GENESIS_SK is destroyed at Network Genesis, this scenario should not happen, but are we ever too safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know those values?
Yeah, we do can know these values.
Assuming GENESIS_SK is destroyed at Network Genesis
shall be OK, as GENESIS_SK is actually not used (and shall not be used) after GENESIS_SPEND generated.
6c2a077
to
dd16544
Compare
7fc6a99
to
850b28f
Compare
{ | ||
/// - verifies that the parent_spends contains self as an output | ||
/// - verifies the sum of total inputs equals to the sum of outputs | ||
pub fn verify_parent_spends(&self, parent_spends: &BTreeSet<SignedSpend>) -> Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering without the middle pay, how the above conditions got all satisfied for the scenario of multiple_inputs to multiple_outputs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like it now trying to use return multiple cash_note, each cn per recipient, i.e. get inputs distributed to outpus explicitly
to resolve this.
So, here, both of the criterias can still be satisfied at the same time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes all this is covered by the distribution algo in UnsignedTransaction
// check for double spend parents | ||
if spends.len() > 1 { | ||
error!("While verifying parents of {unique_key}, found a double spend parent: {spends:?}"); | ||
return Err(TransferError::DoubleSpentParent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually means the spend itself having duplicated ancestors ?
which is different to the scenario that an ancestor got spent already?
maybe it shall give a different name to differiate these two scenarios?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually means the spend itself having duplicated ancestors ?
This means one of the spend's parents has multiple entries and is burnt.
pub fn is_genesis_spend(spend: &SignedSpend) -> bool { | ||
let bytes = spend.spend.to_bytes_for_signing(); | ||
spend.spend.unique_pubkey == *GENESIS_SPEND_UNIQUE_KEY | ||
&& GENESIS_SPEND_UNIQUE_KEY.verify(&spend.derived_key_sig, bytes) | ||
&& is_genesis_parent_tx(&spend.spend.parent_tx) | ||
&& spend.spend.amount == NanoTokens::from(GENESIS_CASHNOTE_AMOUNT) | ||
&& spend.spend.amount() == NanoTokens::from(GENESIS_CASHNOTE_AMOUNT) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know those values?
Yeah, we do can know these values.
Assuming GENESIS_SK is destroyed at Network Genesis
shall be OK, as GENESIS_SK is actually not used (and shall not be used) after GENESIS_SPEND generated.
c8a9195
to
935becf
Compare
@@ -93,11 +111,21 @@ impl UnsignedTransaction { | |||
}) | |||
.collect(); | |||
|
|||
// order inputs by value, re const after sorting | |||
let mut cashnotes_big_to_small = available_cash_notes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shall try to use the small ones first ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we'd like to minimize the amount of Spends created, using big ones first has that effect for now, but it's not optimal over the long run.
In the future I imagine we should create a better algorithm that would optimize that and choose the best options with the closest values as to minimize the amount of spends and avoid using huge Cashnotes for small Txs.
Also, since CashNotes don't have a determined value anymore, we could return the change value to an existing unspent CashNote that would accumulate wealth until it is spent.
All these nice optimizations will not change the API in this PR so that's also nice!
935becf
to
e0d8aeb
Compare
BREAKING CHANGE
BREAKING CHANGE: many types gone, replaced by UnsignedTransaction SignedTransaction
ab59db4
to
9fe6f44
Compare
41193e0
to
8bcab6d
Compare
BREAKING CHANGE
Continuing off @maqi's redesign of Spends in refactor PR #1930
Redesigns the whole transacting flow from
CashNote
s all the way toSpend
with a simpler design:Removing:
OfflineTransfer
: all you need to make a transaction, signedTransferInputs
: amassed data to make a transaction's inputsCashNotesAndSecretKey
: this for inputs tooTransactionBuilder
: this makes a transaction from inputsCashNoteBuilder
: this makes cashnotes from transactionsUnsignedTransfer
: this is a special case when we don't have a key to sign the transactionTransaction
,Input
,Output
: this was in Spendsobfuscationabstraction500
lines of codeReplaced by:
UnsignedTransaction
: all you need to make a transaction, not signedSignedTransaction
: all you need to make a transaction, signedWhat's next
spend_simulation
tests that were using theTransaction
s inSpends
@RolandSherwinUnsignedTransaction::verify
UnsignedTransaction::new
,UnsignedTransaction::sign