8000 Bundle error logging by blakecduncan · Pull Request #377 · getwax/bls-wallet · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Nov 5, 2023. It is now read-only.

Bundle error logging #377

Merged
merged 24 commits into from
Dec 5, 2022
Merged

Bundle error logging #377

merged 24 commits into from
Dec 5, 2022

Conversation

blakecduncan
Copy link
Contributor
@blakecduncan blakecduncan commented Nov 4, 2022

https://loom.com/share/2a2039a17af04e23838561a08b0c6aaf

What is this PR doing?

  • Adding a submit error column to the DB
  • Updating the bundle receipt API call to return a 202 if the bundle exists in the DB
  • New response object for bundle receipt API call (note: this will break demos. It's a simple fix but I want to make sure it is okay with everyone)

Additional work

  • We would need to update examples and the extension because right now, they expect the /bundleReceipt API call to return a 404 when a bundle is pending.

Future improvements

  • Add a status column to the bundles table so that we don't delete bundles when the are successful or fail (we are currently storing the successful bundles in memory)

How can these changes be manually tested?

You can run the zeroAddressError script to trigger a bundle error and log out a message

Does this PR resolve or contribute to any issues?

Resolves #301

Checklist

  • I have manually tested these changes
  • Post a link to the PR in the group chat

Guidelines

  • If your PR is not ready, mark it as a draft
  • The resolve conversation button is for reviewers, not authors
    • (But add a 'done' comment or similar)

@blakecduncan blakecduncan marked this pull request as draft November 4, 2022 12:13
@github-actions github-actions bot added the aggregator Aggregator backend related label Nov 4, 2022
@@ -0,0 +1,50 @@
#!/usr/bin/env -S deno run --allow-net --allow-env --allow-read --allow-write --unstable
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just a script to trigger an error in a bundle for testing

@@ -235,11 +235,16 @@ export default class AggregationStrategy {
let success: boolean;

if (bundleResult.success) {
const [operationResults] = bundleResult.returnValue;
const [operationStatuses, results] = bundleResult.returnValue;

This comment was marked as outdated.

This comment was marked as outdated.

errorArgBytesString,
)[0]; // decoded bytes is a string of the action index that errored.

console.error(errorString)

This comment was marked as outdated.

Comment on lines 240 to 242
// TODO: is it possible to decode this?
// Here is an example when I try to send more ETH than an account has:results =
// results = [ "0x4e487b710000000000000000000000000000000000000000000000000000000000000011" ]

This comment was marked as outdated.

@github-actions github-actions bot removed the clients label Nov 22, 2022
@@ -444,3 +461,89 @@ export default class AggregationStrategy {
return left;
}
}

// The below code is temporary till the functions are exposed in the client module
Copy link
Contributor Author

Choose a reason for hiding this comment

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

After this is merged and a new version is published, I will delete the below code and use the function from the client module

#407

Copy link
Collaborator

Choose a reason for hiding this comment

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

@blakecduncan You can do that now #407 . You can use https://github.com/web3well/bls-wallet/blob/main/docs/local_development.md#aggregator-1 as a guide, but feel free to ping me if you need help.


return { success, fee };
return { success, fee, errorReason };
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Returning the error reason here so that we can link it to a failed row later when we check the index of the failed bundle

@@ -24,6 +24,16 @@ export default function BundleRouter(bundleService: BundleService) {
router.get(
"bundleReceipt/:hash",
async (ctx) => {
// check pending
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Return 202 error message if the bundle is in the DB. Also, pass a submit error in the body

@blakecduncan blakecduncan marked this pull request as ready for review November 22, 2022 16:48
@blakecduncan blakecduncan self-assigned this Nov 22, 2022
Copy link
Collaborator
@jacque006 jacque006 left a comment

Choose a reason for hiding this comment

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

Would be good to have an integration test case(s) for the HTTP 202 path that ensures the bundle lifecycle & error decoding works as expected.

@blakecduncan
Copy link
Contributor Author

Would be good to have an integration test case(s) for the HTTP 202 path that ensures the bundle lifecycle & error decoding works as expected.

Yeah good call, I'll write some tests for this 👍

@github-actions github-actions bot added aggregator-proxy Aggregator proxy related clients labels Nov 29, 2022
@github-actions github-actions bot added the extension Browser extension related label Nov 30, 2022
@voltrevo
Copy link
Collaborator
voltrevo commented Dec 1, 2022

Idk how I'm missing these lint errors

😄. How's your IDE set-up? Are the linting errors showing? Is autofix-on-save working?

@@ -176,6 +178,10 @@ export default class AggregationStrategy {

if (firstFailureIndex !== nil) {
const failedRow = includedRows[firstFailureIndex];
const errorReason = fees[firstFailureIndex].errorReason;
if (errorReason) {
failedRow.submitError = errorReason.message || '';

This comment was marked as resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@voltrevo Yeah that makes sense I'll switch it. I was doing this because I didn't make the column nullable in the DB, so it was setting it by default to an empty string. I updated that per your comment below and was able to make this more consistent with the undefined/nil

@@ -207,6 +213,7 @@ export default class AggregationStrategy {
async #measureFees(bundles: Bundle[]): Promise<{
success: boolean;
fee: BigNumber;
errorReason: OperationResultError | null;

This comment was marked as resolved.

const fee = after.returnValue[0].sub(before.returnValue[0]);
const [operationStatuses, results] = bundleResult.returnValue;

let errorReason: OperationResultError | null = null;

This comment was marked as resolved.

return;
}
});
errorReason = error[0] ?? null;

This comment was marked as resolved.

@@ -24,14 +24,29 @@ export default function BundleRouter(bundleService: BundleService) {
router.get(
"bundleReceipt/:hash",
async (ctx) => {
const pendingBundle = await bundleService.lookupBundle(ctx.params.hash!);
if (pendingBundle) {
ctx.response.status = 202;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think 202 is appropriate here. It's the bundle that's been accepted, not the receipt. Also 'accepted' is supposed to refer to the current request, not the resource you're asking about. More info.

(Possibly 202 is appropriate for the original POST to /bundle, but I'm not actually a fan of worrying about these HTTP nuances.)

On a practical note, if we keep 404 here we can still also provide the submitError, and this way it wouldn't be a breaking change. Wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I get what you're saying. I do like the idea of not doing a breaking change, as there are a good amount of things that have to be updated at this point.

However, I think the /bundleReceipt API call is often used as a status check for a bundle. So my question would be, what should we expect to be returned from this API call? With the approach you recommended, we would keep a 200 status as is (i.e. returns the bundle receipt) and pass the submit error in a 404 response body. That would be fine by me - I think the only thing we aren't communicating explicitly is the bundle status. For example, we could communicate a pending or a failed state (ex: even if it failed once, we may still retry it). Maybe we don't care about that though or it should be a different API endpoint.

@voltrevo What do you think? I'd be happy to hop on a call tomorrow when I get online if you are still around. Also, @jacque006 not sure if you have any thoughts?

Copy link
Collaborator
@voltrevo voltrevo Dec 2, 2022

Choose a reason for hiding this comment

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

I'm not sure we're on the same page here. Definitely sounds like a call is in order.

With the approach you recommended, we would keep a 200 status as is (i.e. returns the bundle receipt) and pass the submit error in a 404 response body.

Did you mean to say 'keep a 200 status'? It seems wrong, and also contradicts the second half of this sentence. At least my reading of it.

To rephrase my suggestion, I think if the bundle is pending, then /bundleReceipt should 404, since there isn't a bundle receipt, but we can also put the submitError in the body of this response. Meaning: "No, there's no receipt (404), and here's why (submitError)".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahh my response was poorly worded. We are on the same page. When I said keep the 200 status, I really meant get rid of my logic to add the 202. You worded it better than I did - that is what I meant to say.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep, we can discuss offline. In general, I have seen services go one of two ways:

  • Use a variety/specific HTTP codes to communicate the state of a resource (200/201/202/403/404/418)
  • Use a limited number of status codes (200/403/404) and use a status field or similar to communicate the state of the resource (pending/failed/succeeded). Some Google Cloud APIs go this route

I think either is fine as long as we are consistent with that pattern on our endpoints and document the possible responses in code. Hopefully most consumers use our clients which can abstract a lot of that away.

const bundleRow: BundleRow = {
id: 0,
hash: "0x0",
submitError: "",

This comment was marked as resolved.

@@ -49,6 +49,7 @@ const sampleRows: BundleRow[] = [
],
signature: ["0x00", "0x00"],
},
submitError: "",

This comment was marked as resolved.


export type BundleReceiptResponse = {
status: string;
submitError: string | null;

This comment was marked as resolved.

export type BundleReceiptResponse = {
status: string;
submitError: string | null;
receipt: BundleReceipt | null;

This comment was marked as resolved.

const bundleReceiptResponse = await aggregator.lookupReceipt(hash);
// If receipt doesn't exist, set to undefined to be consistent with
// the return type
const bundleReceipt = bundleReceiptResponse?.receipt || undefined;
Copy link
Collaborator

Choose a reason for hiding this comment

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

|| undefined is unnecessary (obj?.field produces undefined when field is not there, even when obj is null).

Also prefer ?? over ||.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I was getting a typescript error the BundleReceipt | undefined does not equal BundleReceipt | undefined | null. I think with the changes you recommended above I can fix this.

eligibleAfter: { type: DataType.VarChar },
nextEligibilityDelay: { type: DataType.VarChar },
};

function fromRawRow(rawRow: RawRow): Row {
const parseResult = parseBundleDto(JSON.parse(rawRow.bundle));

console.log('blake..', parseResult);
Copy link
Collaborator

Choose a reason for hiding this comment

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

debug log left here

Copy link
Collaborator
@jacque006 jacque006 left a comment

Choose a reason for hiding this comment

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

👍 from me. :shipit: once @voltrevo is satisfied

@voltrevo voltrevo merged commit 1cf7159 into main Dec 5, 2022
@voltrevo voltrevo deleted the bundleErrorLogging branch December 5, 2022 02:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
aggregator Aggregator backend related aggregator-proxy Aggregator proxy related clients extension Browser extension related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add better failure messaging for bundles
3 participants
0