-
Notifications
You must be signed in to change notification settings - Fork 155
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
mobilecoind: add support for mixed transactions, including those with SCIs in them #3214
Conversation
752a29d
to
13cdb77
Compare
@@ -82,11 +83,16 @@ impl SignedContingentInput { | |||
/// Note: This does check any other rules like tombstone block, or | |||
/// confirm proofs of membership, which are normally added only when this | |||
/// is incorporated into a transaction | |||
pub fn validate(&self) -> Result<(), SignedContingentInputError> { | |||
pub fn validate(&self) -> Result<SignedContingentInputAmounts, SignedContingentInputError> { |
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 decided to change the validate function so that it returns an object which contains lists of all the amounts of things that it unmasked during validation.
This makes it less complicated to find all those amounts after validating the SCI, and avoids the overhead of unmasking the TxOut's again and again.
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.
Nice, I think this can be useful in the DEQS
ZeroPartialFillChange, | ||
/// Partial fill output amount was zero | ||
ZeroPartialFillOutput, |
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 is not currently an error from the consensus network's point of view, but if we change input rules validation to use U64Ratio
, then it probably will be.
I think that's okay, there's not any interesting use-case for having zero-value partial fill outputs.
It just happens to work today without an error because I wrote the code in a pretty low-level way that didn't require constructing U64Ratio
.
82b04fa
to
47bd256
Compare
47bd256
to
25c4626
Compare
this reduces code duplication, and the fact that tests are still passing convinces me that the input selection and change calculation stuff in build_mixed_transaction is likely all correct, since this puts way more test coverage on that function -- all the APIs are now going through build_mixed_transaction
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.
Very nice work, got some small comments but over all looks great.
@@ -82,11 +83,16 @@ impl SignedContingentInput { | |||
/// Note: This does check any other rules like tombstone block, or | |||
/// confirm proofs of membership, which are normally added only when this | |||
/// is incorporated into a transaction | |||
pub fn validate(&self) -> Result<(), SignedContingentInputError> { | |||
pub fn validate(&self) -> Result<SignedContingentInputAmounts, SignedContingentInputError> { |
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.
Nice, I think this can be useful in the DEQS
…tests this addresses some Eran comments, we think after review and testing that the fallback fee constant is kind of dangerous now that we have a multitoken ecosystem
candidate_block_version, | ||
last_block_info.network_block_version, | ||
); | ||
.ok_or_else(|| Error::TxBuild("Token cannot be used to pay fees".into()))?; |
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 is what we do now instead of the FALLBACK_FEE
it's possible that we should give this error if the token id is not in the last_block_info, even if the user provided a fee value
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.
❓ for the fee here my understanding is that if the request doesn't have a sufficient fee the transaction will eventually get rejected by consensus.
What I'm not sure about is if the user provides a larger fee than required. I'm guessing that consensus will gladly take that full fee value??..
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, in the scenario that there is network congestion, users have to pay higher fees to get their transactions through
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, it will happily take a larger fee. Which is why this FALLBACK_FEE was problematic - users might end up unexpectedly paying higher fees than necessary
they aren't in the request, they are also visible in the Tx and so they don't need to be duplicated
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.
The main blocker is making sure the proto changes are correct and that falling back to MOB is what we want to do if these protos happen to talk to an older API.
What I've tried to do is, not change any of the request types of the older APIs -- falling back to MOB is a hazard, so that's why there's an Only new APIs use (I understand your concern now that, old TxProposal could be deserialized by a new client to have a bunch of spurious zeroes, but I also think that is going to be okay, because I don't think old TxProposals actually get passed to new clients in any actual workflow using mobilecoind.) |
Co-authored-by: Nick Santana <[email protected]>
Co-authored-by: Nick Santana <[email protected]>
Co-authored-by: Nick Santana <[email protected]>
… SCIs in them (#3214) * add support for mixed transactions, including those with SCIs in them * make build_transaction call to build_mixed_transaction this reduces code duplication, and the fact that tests are still passing convinces me that the input selection and change calculation stuff in build_mixed_transaction is likely all correct, since this puts way more test coverage on that function -- all the APIs are now going through build_mixed_transaction * add test coverage * fixup api docs about fees * cleanup stuff about Outlay vs OutlayV2 comparisons * add some error handling for if change overflows a u64 * improve test coverage around counterparty change output * test SCIs in the response * remove fallback fee, use a better fee-map for mobilecoind tests, fix tests this addresses some Eran comments, we think after review and testing that the fallback fee constant is kind of dangerous now that we have a multitoken ecosystem * clippy * clear out sci proofs when adding sci records to TxProposal they aren't in the request, they are also visible in the Tx and so they don't need to be duplicated * Update mobilecoind/api/proto/mobilecoind_api.proto Co-authored-by: Nick Santana <[email protected]> * Update transaction/extra/src/signed_contingent_input.rs Co-authored-by: Nick Santana <[email protected]> * Update mobilecoind/api/proto/mobilecoind_api.proto Co-authored-by: Nick Santana <[email protected]> * update many code comments, per review * update more code comments, add more tests to util-u64-ratio --------- Co-authored-by: Nick Santana <[email protected]>
This adds a new endpoint to mobliecoind called
generate_mixed_transaction
.Unlike the
generate_transaction
endpoint, it does not assume that every outlay has the token id of the fee. Instead the request has afee_token_id
and each outlay is now anOutlayV2
which has a token id parameter.Outlay
is used both in the requests and responses forgenerate_transaction
, so what I decided to do is extendOutlay
toOutlayV2
, which has a token id parameter, andTxProposal
now containsOutlayV2
. That protobuf extension was backwards compatible. All the historical requests, though, still useOutlay
.Clients that only know about
Outlay
will still deserializeTxProposal
correctly, ignoring the new field. Clients that know aboutOutlayV2
will be able to see the token id of each outlay.The
generate_transaction
request type is not changed, it still uses the old outlay type. This is because I think it would be ambiguous -- old clients expect to set that field using thetoken_id
parameter which governs the fee. If the server would default that to zero, it could change the meaning of requests coming from old clients.The
generate_mixed_transaction
request type usesOutlayV2
as the parameter.Let me know if you see a problem with this compatibility strategy, happy to revisit it.
This PR increased in scope from what I originally planned -- to implement this stuff correctly, we need to be able to track balance changes coming from SCIs across several tokens, and then aggregate all those changes across the whole transaction to figure out the sizes of change outputs. So I added some functionality to
SignedContingentInput
to help with this.Additionally, I found myself doing a lot of manual
u64
andu128
arithmetic which is a bit subtle. In earlier PRs Eran had suggested that we should figure out a way to DRY all that up, but I didn't see a good way and it was only used in two places at the time. This time around, now that I have to do all that yet again, I decided to make such a way to reuse code, which is now a small utility classU64Ratio
.I'm happy to try to split out the lower level changes into a separate PR that can be reviewed first, but I feel like it's helpful to see what I'm trying to accomplish in order to scope those changes.
In latest commits, we have also removed the
FALLBACK_FEE
constant, which was unexpected and thought to be potentially hazardous during testing of what happens if you try to pay a fee in eusd and you don't specify a fee. If the user doesn't specify a fee, and the blockchain doesn't give a minimum fee for a particular token, then an error is returned that this token cannot be used to pay fees.