Skip to content
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

rpc: add SetPendingTransferProofCourierAddr endpoint to fix erroneous courier addresses #1097

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ffranr
Copy link
Contributor

@ffranr ffranr commented Aug 21, 2024

This PR introduces a new RPC endpoint, SetPendingTransferProofCourierAddr, which allows overriding the proof courier address for a pending asset transfer output. This enhancement directly addresses the issue of correcting erroneous courier addresses during asset transfers as described in issue #1082.

This commit renames the ChainPorter.transferReceiverProof method for
clarity, reflecting that multiple proofs may be transferred. The
documentation has also been updated accordingly.
This commit introduces the `position` field to the `TransferOutput`
proto message. This field serves as a unique index, enabling precise
identification of an output within a given transfer.
This commit adds a new RPC endpoint which can be used to override the
proof courier address for a pending asset transfer output.
@ffranr ffranr self-assigned this Aug 21, 2024
@ffranr
Copy link
Contributor Author

ffranr commented Aug 21, 2024

I'm looking for early feedback on the general direction of this PR.

This PR is in draft for the following reasons:

  • Missing itest.
  • Updated proof courier address is not updated on dist (stored to the database).

@coveralls
Copy link

Pull Request Test Coverage Report for Build 10490103886

Details

  • 0 of 76 (0.0%) changed or added relevant lines in 2 files are covered.
  • 20 unchanged lines in 6 files lost coverage.
  • Overall coverage decreased (-0.06%) to 40.353%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tapfreighter/chain_porter.go 0 5 0.0%
rpcserver.go 0 71 0.0%
Files with Coverage Reduction New Missed Lines %
rpcserver.go 1 0.0%
tappsbt/create.go 2 53.22%
asset/asset.go 2 81.35%
tapdb/universe.go 4 80.91%
tapgarden/caretaker.go 4 68.5%
tapdb/multiverse.go 7 60.32%
Totals Coverage Status
Change from base Build 10477817019: -0.06%
Covered Lines: 23942
Relevant Lines: 59331

💛 - Coveralls

Copy link
Member

@guggero guggero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a first pass, looks like what we need. Have some naming suggestions though.

@@ -40,6 +40,10 @@ var (
Entity: "assets",
Action: "read",
}},
"/taprpc.TaprootAssets/SetPendingTransferProofCourierAddr": {{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should go with just UpdateTransferOutput and only allow the proof courier address to be updated for now. And we'll just return an error if the selected transfer output isn't pending.
IMO we don't have to put the whole documentation of a method into its name ;-)

message SetPendingTransferProofCourierAddrRequest {
// The new proof courier address to use for the target transfer output proof
// delivery.
string new_proof_courier_addr = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe to make it more clear we can only update this field (for now?), we could put that into a new sub-message.

So something like this:

message UpdateTransferOutput {
    // The hexadecimal encoded transaction ID (txid) of the anchor transaction
    // for the target transfer.
    string anchor_txid = 1;

    // Script public key of the target transfer output.
    bytes transfer_output_script_pub_key = 2;

    // The position of the output in the transfer output list.
    uint64 transfer_output_position = 3;

    TransferOutputModify modify_params = 4;
}

message TransferOutputModify {
    string proof_courier_addr = 1;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the current definition I think this is the only reasonable field to change rn, but I agree that using a sub-message is a worthwhile change.

}

// Unmarshal the transfer output script key public key.
outputScriptKey, err := parseUserKey(req.TransferOutputScriptPubKey)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the pubkey is a safety net to make sure the user really specified the right one?

ctx, anchorTxHash, true,
)
if err != nil {
return nil, fmt.Errorf("failed to query parcels: %w", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user will run into this if they specify a completed transfer. Perhaps we should mention this in the error message, so something like "parcel not found in pending parcels"?

// The anchoring transaction of target parcel must have already
// been confirmed on-chain.
if pendingParcel.AnchorTxBlockHash.IsNone() {
continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this matter? Maybe we want to update before we reached a confirmation?
I assume it has something to do with how we insert a new parcel, see comment below.


// Request delivery of the updated parcel.
pendingParcel := tapfreighter.NewPendingParcel(targetParcel)
_, err = r.cfg.ChainPorter.RequestShipment(pendingParcel)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this be handled properly and not lead to duplicates? Shouldn't we add the possibility to update an existing parcel instead?


// The hexadecimal encoded transaction ID (txid) of the anchor transaction
// for the target transfer.
string anchor_txid = 2;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be the full outpoint, not just the TXID? Otherwise we aren't uniquely identifying the transfer output.

The transfer output list is per-transfer, but IIUC there is no requirement of exactly 1 transfer per TX (can I combine multiple transfers into one TX?)

So the suggested field would be anchor_outpoint, then in the RPC call implementation you could add a filter on pendingParcel.Outputs for outputs with a matching Anchor.OutPoint.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a more concrete example, If there are two transfers with the same TXID, the result of QueryParcels will contain the outputs of both transfers.

If I only use outputScriptKey or TransferOutputPosition to specify the TransferOutput, that could match outputs from both transfers, when we want to match exactly one TransferOutput.

@dstadulis dstadulis added this to the v0.4.2 milestone Aug 24, 2024
@Roasbeef Roasbeef modified the milestones: v0.4.2, v0.5 Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🏗 In progress
Development

Successfully merging this pull request may close these issues.

6 participants