-
Notifications
You must be signed in to change notification settings - Fork 157
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(genLocalState) - debugging utility for log fetching and local maci state generation #758
Conversation
Isn't #723 a request to add the fetchLogs command back? |
const lastBlock = endBlock ? endBlock : await provider.getBlockNumber() | ||
|
||
// Fetch event logs in batches | ||
for (let i = fromBlock; i < lastBlock; i += blocksPerRequest + 1) { |
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 believe it's worthwhile to implement test code to avoid issues like the previous case of duplicate logs. Please note that such duplicate logs resulted in generating an incorrect proof.
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.
// init() should only be called up to 1 time
assert(
initLogs.length <= 1,
'More than 1 init() event detected which should not be possible',
)
If there are duplicate logs, this will throw.
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.
There are signUpLogs, mergeStateAqSubRootsLogs, mergeStateAqLogs, deployPollLogs, publishMessageLogs...etc. Without adequate tests, confidently predicting the impact of these changes on production becomes challenging. What are your thoughts on this?
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 code incorporates the fix needed to ensure we do not fetch duplicate logs - the same fix that the project encountering the issue proposed + We do have e2e and integration tests which use this genProof and have been working correctly.
29e3946
to
b566bc0
Compare
sure, but there was missing context about that, |
It’s challenging to view File Output Capability: The original Code Reference: fetchLogs usage Independent Usability for Debugging: |
b566bc0
to
9752368
Compare
1a2a444
to
4b6117e
Compare
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 fetchLogs
command, as it's currently implemented, seems to be misnamed as it does more than just fetching logs—it generates and outputs the MACI state, which is an entirely different responsibility. This oversteps the expected functionality of a log-fetching utility, leading to unnecessary complexity and potential confusion:
- The command requires contract ABIs and the coordinator's private key, which are beyond the scope of simply fetching logs. These requirements suggest operations relevant to MACI state generation and proof creation, not log retrieval.
- It performs operations with significant time complexity, such as array pushes and sorts on the entire log dataset, which are superfluous for log fetching; these operations incurs O(n) and O(n log n) time complexities.
- The inclusion of the coordinator's private key raises security concerns, as it's not necessary for fetching logs and should not be requested without cause
This conflation of concerns could be misleading and might introduce inefficiencies or security vulnerabilities. A command should do one thing and do it well—fetching logs shouldn't involve generating state. Consider refactoring to separate these concerns, ensuring the command name and its functionality are in alignment, and that it adheres to the principle of least privilege by not requiring sensitive information where it's not needed.
for (let i = fromBlock; i < lastBlock; i += blocksPerRequest + 1) { | ||
const toBlock = (i + blocksPerRequest) >= lastBlock ? undefined : i + blocksPerRequest | ||
|
||
const tmpInitLogs = await provider.getLogs({ |
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.
Consider (Rate Limiting): It's worth noting that this PR addresses the eth_getLogs
rate limit by splitting up requests to stay within the 10K logs response cap. However, Alchemy also implements rate limiting through Compute Units Per Second (CUPS), which applies to the API key as a whole. While this PR doesn't need to address CUPS limits right now, it's an important aspect to keep in mind for the future to ensure our application remains within Alchemy's operational boundaries (or generally other node provider services as well).
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.
Added a sleep flag (optional) which users can use to add a sleep in between each getLog request :) - great suggestion thanksss
cli/ts/fetchLogs.ts
Outdated
|
||
// ensure we have at least one address | ||
if ((!contractAddrs||!contractAddrs["MACI"]||!contractAddrs[pollArtifactName]) && !args.maci_contract && !args.poll_contract) { | ||
console.error('Error: MACI and Poll contract addresses are empty or this poll Id does not exist') |
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 error message does not guide the user on how to resolve the issue. It would be beneficial to specify which command-line arguments the user needs to pass to rectify this error. For example, we could enhance the error message to something like:
- Error: MACI and Poll contract addresses are empty or this poll Id does not exist. Please ensure you include '--maci-contract' and '--poll-contract' with the respective contract addresses as arguments.
This clarification would help users to self-diagnose and fix the issue without delving into the codebase or documentation.
cli/ts/fetchLogs.ts
Outdated
const pollArtifactName = `Poll-${pollId}` | ||
|
||
// ensure we have at least one address | ||
if ((!contractAddrs||!contractAddrs["MACI"]||!contractAddrs[pollArtifactName]) && !args.maci_contract && !args.poll_contract) { |
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 conditional check seems to allow the execution to proceed even when poll_contract
is not provided, which results in a TypeError
at the address validation step:
% node build/index.js fetchLogs -n 150 -o fetchlogs.log -sk 'macisk.aa' -x '0x37091e3064c20637950e007500049477B0b96636'
/Users/daehyun/workspace/pse/maci/cli/ts/utils.ts:33
return address.match(/^0x[a-fA-F0-9]{40}$/) != null
^
TypeError: Cannot read properties of undefined (reading 'match')
at validateEthAddress (/Users/daehyun/workspace/pse/maci/cli/ts/utils.ts:33:20)
at /Users/daehyun/workspace/pse/maci/cli/ts/fetchLogs.ts:143:28
at step (/Users/daehyun/workspace/pse/maci/cli/build/fetchLogs.js:33:23)
at Object.next (/Users/daehyun/workspace/pse/maci/cli/build/fetchLogs.js:14:53)
at /Users/daehyun/workspace/pse/maci/cli/build/fetchLogs.js:8:71
at new Promise (<anonymous>)
at __awaiter (/Users/daehyun/workspace/pse/maci/cli/build/fetchLogs.js:4:12)
at fetchLogs (/Users/daehyun/workspace/pse/maci/cli/ts/fetchLogs.ts:121:35)
at /Users/daehyun/workspace/pse/maci/cli/ts/index.ts:249:24
at step (/Users/daehyun/workspace/pse/maci/cli/build/index.js:34:23)
at Object.next (/Users/daehyun/workspace/pse/maci/cli/build/index.js:15:53)
at /Users/daehyun/workspace/pse/maci/cli/build/index.js:9:71
at new Promise (<anonymous>)
at __awaiter (/Users/daehyun/workspace/pse/maci/cli/build/index.js:5:12)
at main (/Users/daehyun/workspace/pse/maci/cli/ts/index.ts:137:14)
at Object.<anonymous> (/Users/daehyun/workspace/pse/maci/cli/ts/index.ts:254:5)
To prevent this runtime error, we should consider making the poll_contract
argument mandatory or add a more descriptive error message when it's missing. This would improve the user experience by providing immediate and clear feedback on what is required for successful execution.
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.
mm if you do not pass a poll ID, it will default to poll ID number 0.. where are you trying this? on a local network or on a live testnet?
cli/ts/fetchLogs.ts
Outdated
) | ||
|
||
parser.addArgument( | ||
['-e', '--eth-provider'], |
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 --eth-provider
argument is essential for the operation of this script as it stands. Omitting this results in a NETWORK_ERROR
, indicating that the script cannot detect the network.
% node build/index.js fetchLogs -n 150 -o fetchlogs.log -sk 'macisk.aaa' -x '0x37091e3064c20637950e007500049477B0b96636' -p '0x37091e3064c20637950e007500049477B0b96636'
/Users/daehyun/workspace/pse/maci/cli/node_modules/@ethersproject/logger/src.ts/index.ts:269
const error: any = new Error(message);
^
Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.2)
at Logger.makeError (/Users/daehyun/workspace/pse/maci/cli/node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
at Logger.throwError (/Users/daehyun/workspace/pse/maci/cli/node_modules/@ethersproject/logger/src.ts/index.ts:281:20)
at JsonRpcProvider.<anonymous> (/Users/daehyun/workspace/pse/maci/cli/node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:483:23)
at step (/Users/daehyun/workspace/pse/maci/cli/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:48:23)
at Object.throw (/Users/daehyun/workspace/pse/maci/cli/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:29:53)
at rejected (/Users/daehyun/workspace/pse/maci/cli/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:21:65)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
Could we adjust the argument's configuration to be mandatory?
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.
could it be that you were not running a hardhat local node? if you do not pass it as argument then it will default to the local rpc.. if no local node is running it will ofc give this error
cli/ts/fetchLogs.ts
Outdated
maciPrivkeyGroup.addArgument( | ||
['-sk', '--privkey'], |
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.
Considering the main functionality of fetchLogs
command is to retrieve event logs, including a private key argument might not be required. Removing it could simplify the command-line interface and minimize potential security concerns.
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 needed to generate the maci state :)
cli/ts/fetchLogs.ts
Outdated
// fetch abis | ||
const [ maciContractAbi ] = parseArtifact('MACI') | ||
const [ pollContractAbi ] = parseArtifact('Poll') | ||
|
||
const maciContract = new ethers.Contract( | ||
maciAddress, | ||
maciContractAbi, | ||
provider, | ||
) | ||
|
||
const pollContract = new ethers.Contract( | ||
pollAddress, | ||
pollContractAbi, | ||
provider | ||
) |
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.
maciContract
and pollContract
instances are created here but do not appear to be used later in the code. If these instances are not required for subsequent operations, their creation could unnecessarily consume resources and possibly lead to confusion about their purpose. It might be worth considering their removal to streamline the codebase unless there is a future use for them that is not immediately apparent. This would also help in maintaining clean and efficient code.
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.
removed thanks
cli/ts/genProofs.ts
Outdated
if (args.state_file) { | ||
// @todo actually read the file first | ||
const content = JSON.parse(fs.readFileSync(args.state_file, 'utf-8').toString()) | ||
maciState = MaciState.fromJSON(content) | ||
// ensure we merge all messages | ||
maciState.polls.forEach((poll: Poll) => poll.mergeAllMessages()) | ||
} else { |
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 change introduce to reading from a state file if args.state_file
is provided, and then generating the proof based on the JSON content. However, there appears to be no test coverage to verify the correctness of the serialization/deserialization process and the subsequent proof generation using the parsed data. Could we introduce unit test that validate the correct functioning of the proof generation when using parsed data?
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.
Sure I can add one e2e! unit tests for deserialization and serialization are in the core package btw
fromBlock = txn.blockNumber | ||
if (args.state_file) { | ||
// @todo actually read the file first | ||
const content = JSON.parse(fs.readFileSync(args.state_file, 'utf-8').toString()) |
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 assumes that the input file format is correct. It's important to handle potential exceptions that could arise from incorrect file formats. Adding error handling for the JSON parsing process could prevent runtime errors and improve the robustness of the script.
Ok so the file now has a different name, |
4b6117e
to
808ac9d
Compare
|
||
echo "gen proofs ..." | ||
|
||
# generate the local state |
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 demonstration of how to use new command!
…r batch and end block
…rialization into a new object
…sure we read the file in genProofs
…s correctly and fix bug in curentMessageBatchIndex
… limiting, change utility name, add better error handling
…the MaciState constructor
…t as parameter when de-serializing the object
…keep one for each loop iteration
…setter function for it
47eb6f8
to
5002078
Compare
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.
LGTM!
fix #723
fix #447
How to test:
Run
tests/vanilla/testPreFetch.sh