This repository has been archived by the owner on Nov 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add getOperationResults to bls-wallet-clients to allow consumers to more easily get at operation errors. Change existing test case to use getOperationResults. Add message to require used to prevent ownership changes to proxy admin.
- Loading branch information
Showing
5 changed files
with
135 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { BigNumber, ContractReceipt, utils } from "ethers"; | ||
import { ActionData } from "./signer"; | ||
|
||
type OperationResultError = { | ||
actionIndex: BigNumber; | ||
message: string; | ||
}; | ||
|
||
export type OperationResult = { | ||
walletAddress: string; | ||
nonce: BigNumber; | ||
actions: ActionData[]; | ||
success: Boolean; | ||
results: string[]; | ||
error?: OperationResultError; | ||
}; | ||
|
||
const getError = ( | ||
success: boolean, | ||
results: string[], | ||
): OperationResultError | undefined => { | ||
if (success) { | ||
return undefined; | ||
} | ||
|
||
// Single event "WalletOperationProcessed(address indexed wallet, uint256 nonce, bool success, bytes[] results)" | ||
// Get the first (only) result from "results" argument. | ||
const [errorResult] = results; | ||
// remove methodId (4bytes after 0x) | ||
const errorArgBytesString = `0x${errorResult.substring(10)}`; | ||
const errorString = utils.defaultAbiCoder.decode( | ||
["string"], | ||
errorArgBytesString, | ||
)[0]; // decoded bytes is a string of the action index that errored. | ||
|
||
const splitErrorString = errorString.split(" - "); | ||
if (splitErrorString.length !== 2) { | ||
throw new Error("unexpected error message format"); | ||
} | ||
|
||
return { | ||
actionIndex: BigNumber.from(splitErrorString[0]), | ||
message: splitErrorString[1], | ||
}; | ||
}; | ||
|
||
export const getOperationResults = ( | ||
txnReceipt: ContractReceipt, | ||
): OperationResult[] => { | ||
if (!txnReceipt.events || !txnReceipt.events.length) { | ||
throw new Error( | ||
`no events found in transaction ${txnReceipt.transactionHash}`, | ||
This comment has been minimized.
Sorry, something went wrong. |
||
); | ||
} | ||
|
||
const walletOpProcessedEvents = txnReceipt.events.filter( | ||
(e) => e.event === "WalletOperationProcessed", | ||
); | ||
if (!walletOpProcessedEvents.length) { | ||
throw new Error( | ||
`no WalletOperationProcessed events found in transaction ${txnReceipt.transactionHash}`, | ||
); | ||
} | ||
|
||
return walletOpProcessedEvents.reduce<OperationResult[]>( | ||
(opResults, { args }) => { | ||
if (!args) { | ||
throw new Error("WalletOperationProcessed event missing args"); | ||
} | ||
const { wallet, nonce, actions: rawActions, success, results } = args; | ||
|
||
const actions = rawActions.map( | ||
({ | ||
ethValue, | ||
contractAddress, | ||
encodedFunction, | ||
}: { | ||
ethValue: BigNumber; | ||
contractAddress: string; | ||
encodedFunction: string; | ||
}) => ({ | ||
ethValue, | ||
contractAddress, | ||
encodedFunction, | ||
}), | ||
); | ||
const error = getError(success, results); | ||
|
||
return [ | ||
...opResults, | ||
{ | ||
walletAddress: wallet, | ||
nonce, | ||
actions, | ||
success, | ||
results, | ||
error, | ||
}, | ||
]; | ||
}, | ||
[], | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
It looks like there are a few test cases here that do not have tests written for them. Do we not want to test these different code paths? E.g. lines 51-53, 60-62, 67-69.
I guess a wider question may be what is our philosophy on unit tests and how much do we want to test our code?