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

feat(rpc): Implement an RPC transaction queue #4015

Merged
merged 28 commits into from
Apr 12, 2022
Merged

feat(rpc): Implement an RPC transaction queue #4015

merged 28 commits into from
Apr 12, 2022

Conversation

oxarbitrage
Copy link
Contributor

@oxarbitrage oxarbitrage commented Mar 31, 2022

Motivation

When send_raw_transaction rpc method is called, transactions can fail to get into the mempool. We need a queue of transactions created by the rpc call that can resubmit this failed transactions at a later time (after a block gets added).

Close #3654 if merged.

Solution

An rpc queue was implemented where retries are done.

Review

I think the code is pretty much complete now and have some decent test coverage. @jvff or @teor2345 will be good candidates for the review.

Reviewer Checklist

  • Code implements Specs and Designs
  • Tests for Expected Behaviour
  • Tests for Errors

Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

This looks like a good design, I like the way you have separated the code out into different structs with clear roles. And it achieves the goals of the retry queue ticket.

Here are some alternative ways to achieve the same goals. And some things we need to be careful about. Let me know what you think!

Performance

I think we'll get better performance without the Mutex.

Here is how we could get the transactions instead:

  • RpcImpl::send_raw_transaction() ->
  • RpcImpl.transaction_sender ->
  • channel ->
  • Runner::run receiver

To make that happen, we could do something like:

  1. Move the channel sender to RpcImpl
  2. Move the channel receiver to Runner, and listen at the start of each run loop
  3. Remove the Listener, its task, and the Mutex

Denial of Service

We're getting transactions from users all over the internet. Some of them might send lots of transactions, so we need to handle that well.

Currently, there is no limit on the size of the Queue.

And if the mpsc channel is full, it will block the send_raw_transaction RPC response until the next Runner loop. (The blocking happens after the changes above. Without them, the mutex might cause deadlocks.)

It's ok to drop extra transactions, because we already sent them to the mempool once. (I like the way this PR does that separately.)

Here are some ways to drop extra transactions:

  1. Use a broadcast channel to automatically drop the oldest transactions when the channel is full
  2. Add transactions to the front of the Queue, and remove them from the back if the queue gets full. You can use an IndexMap as an ordered HashMap.

This is similar to what the mempool does with its downloads and internal storage.

zebra-rpc/src/queue.rs Outdated Show resolved Hide resolved
@teor2345

This comment was marked as resolved.

zebra-rpc/src/queue.rs Outdated Show resolved Hide resolved
@oxarbitrage oxarbitrage marked this pull request as ready for review April 2, 2022 21:32
@oxarbitrage oxarbitrage requested a review from a team as a code owner April 2, 2022 21:32
@oxarbitrage oxarbitrage requested review from dconnolly and removed request for a team April 2, 2022 21:32
@teor2345 teor2345 added C-enhancement Category: This is an improvement P-Medium ⚡ A-rpc Area: Remote Procedure Call interfaces do-not-merge Tells Mergify not to merge this PR lightwalletd any work associated with lightwalletd labels Apr 3, 2022
@teor2345
Copy link
Contributor

teor2345 commented Apr 3, 2022

@oxarbitrage I can do a review if you'd like, did you want to do it on a video call?

I think that will make it easier for me to understand some of the details.

@teor2345 teor2345 removed the do-not-merge Tells Mergify not to merge this PR label Apr 4, 2022
* Check for panics in the RPC transaction queue

* Add missing pin! and abort in the start task

* Check for transaction queue panics in tests
@teor2345
Copy link
Contributor

teor2345 commented Apr 7, 2022

In PR #4046 I changed the return type of a method, and fixed up all the call sites.

But I think it's now used in more tests on the main branch.

I'll push a fix today.

Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

It was a trivial fix in a new test on the main branch, so I'm going to re-approve the PR with my fix.

mergify bot added a commit that referenced this pull request Apr 7, 2022
@teor2345
Copy link
Contributor

This PR failed with a temporary authorisation error:

#28 [auth] zealous-zebra/zebra/zebrad-test:pull,push token for us-docker.pkg.dev
[2031](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2031)
#28 DONE 0.0s
[2032](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2032)

[2033](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2033)
#27 exporting to image
[2034](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2034)
#27 pushing layers 0.6s done
[2035](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2035)
#27 ERROR: failed to authorize: failed to fetch oauth token: unexpected status: 401 Unauthorized
[2036](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2036)
------
[2037](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2037)
 > importing cache manifest from us-docker.pkg.dev/zealous-zebra/zebra/zebrad-test:4058-merge-buildcache:
[2038](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2038)
------
[2039](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2039)
------
[2040](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2040)
 > exporting to image:
[2041](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2041)
------
[2042](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2042)
error: failed to solve: failed to fetch oauth token: unexpected status: 401 Unauthorized
[2043](https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2043)
Error: buildx failed with: error: failed to solve: failed to fetch oauth token: unexpected status: 401 Unauthorized

https://github.com/ZcashFoundation/zebra/runs/5865028642?check_suite_focus=true#step:9:2043

@teor2345
Copy link
Contributor

@Mergifyio refresh

@mergify
Copy link
Contributor

mergify bot commented Apr 10, 2022

refresh

✅ Pull request refreshed

mergify bot added a commit that referenced this pull request Apr 10, 2022
@teor2345
Copy link
Contributor

The merge queue's sync past mandatory checkpoint step failed with:

Error: No such container: klt-sync-checkpoint-4076-merge-da7aefa-yhww
https://github.com/ZcashFoundation/zebra/runs/5963709536?check_suite_focus=true#step:9:115

@teor2345
Copy link
Contributor

@Mergifyio update

@mergify
Copy link
Contributor

mergify bot commented Apr 10, 2022

update

✅ Branch has been successfully updated

mergify bot added a commit that referenced this pull request Apr 11, 2022
@gustavovalverde
Copy link
Member

@Mergifyio requeue

@mergify
Copy link
Contributor

mergify bot commented Apr 12, 2022

requeue

✅ The queue state of this pull request has been cleaned. It can be re-embarked automatically

mergify bot added a commit that referenced this pull request Apr 12, 2022
@teor2345 teor2345 merged commit d097697 into main Apr 12, 2022
@teor2345 teor2345 deleted the issue3654 branch April 12, 2022 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rpc Area: Remote Procedure Call interfaces C-enhancement Category: This is an improvement lightwalletd any work associated with lightwalletd
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Retry adding send_raw_transaction to the mempool after missing UTXO failures
3 participants