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

Fix Fetch.fetchActions and add new fetchActions method for external use #843

Merged
merged 3 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/lib/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ async function fetchActions(
) {
if (!graphqlEndpoint)
throw new Error(
'fetchEvents: Specified GraphQL endpoint is undefined. Please specify a valid endpoint.'
'fetchActions: Specified GraphQL endpoint is undefined. Please specify a valid endpoint.'
);
const { publicKey, actionStates, tokenId } = accountInfo;
let [response, error] = await makeGraphqlRequest(
Expand Down Expand Up @@ -824,6 +824,7 @@ async function fetchActions(

if (isSameAccountUpdate && !isLastAction) {
currentActionList.push(data);
currentAccountUpdateId = accountUpdateId;
Comment on lines 825 to +827
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this supposed to fix the bug that you mention? If so, I don't see how it can. The if branch is only executed when we had accountUpdateId === currentAccountUpdateId, so the new line currentAccountUpdateId = accountUpdateId; does nothing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is a simple fix, in fact you can see that the currentAccountUpdateId will be updated after the other branches end, and this problem is caused by the lack of this processing due to the direct return

Copy link
Collaborator

@mitschabaude mitschabaude Apr 11, 2023

Choose a reason for hiding this comment

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

I don't follow. Can you explain how setting currentAccountUpdateId to accountUpdateId can change anything if currentAccountUpdateId is already equal to accountUpdateId, which was tested in the line above (isSameAccountUpdate)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mitschabaude Got you, I made a mistake, lol 😂
Please ignore this modification
I will make a new pull request with the correct fix

return;
} else if (isSameAccountUpdate && isLastAction) {
currentActionList.push(data);
Expand Down
58 changes: 58 additions & 0 deletions src/lib/mina.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export {
accountCreationFee,
sendTransaction,
fetchEvents,
fetchActions,
getActions,
FeePayerSpec,
ActionStates,
Expand Down Expand Up @@ -332,6 +333,11 @@ interface Mina {
tokenId?: Field,
filterOptions?: Fetch.EventActionFilterOptions
) => ReturnType<typeof Fetch.fetchEvents>;
fetchActions: (
publicKey: PublicKey,
actionStates?: ActionStates,
tokenId?: Field
) => ReturnType<typeof Fetch.fetchActions>;
getActions: (
publicKey: PublicKey,
actionStates?: ActionStates,
Expand Down Expand Up @@ -573,6 +579,13 @@ function LocalBlockchain({
async fetchEvents(publicKey: PublicKey, tokenId: Field = TokenId.default) {
return events?.[publicKey.toBase58()]?.[TokenId.toBase58(tokenId)] ?? [];
},
async fetchActions(
publicKey: PublicKey,
actionStates?: ActionStates,
tokenId: Field = TokenId.default
) {
return this.getActions(publicKey, actionStates, tokenId);
},
getActions(
publicKey: PublicKey,
actionStates?: ActionStates,
Expand Down Expand Up @@ -840,6 +853,33 @@ function Network(input: { mina: string; archive: string } | string): Mina {
filterOptions
);
},
async fetchActions(
publicKey: PublicKey,
actionStates?: ActionStates,
tokenId: Field = TokenId.default
) {
let pubKey = publicKey.toBase58();
let token = TokenId.toBase58(tokenId);
let { fromActionState, endActionState } = actionStates ?? {};
let fromActionStateBase58 = fromActionState
? fromActionState.toString()
: undefined;
let endActionStateBase58 = endActionState
? endActionState.toString()
: undefined;

return Fetch.fetchActions(
{
publicKey: pubKey,
actionStates: {
fromActionState: fromActionStateBase58,
endActionState: endActionStateBase58,
},
tokenId: token,
},
archiveEndpoint
);
},
getActions(
publicKey: PublicKey,
actionStates?: ActionStates,
Expand Down Expand Up @@ -941,6 +981,13 @@ let activeInstance: Mina = {
fetchEvents(_publicKey: PublicKey, _tokenId: Field = TokenId.default) {
throw Error('must call Mina.setActiveInstance first');
},
fetchActions(
_publicKey: PublicKey,
_actionStates?: ActionStates,
_tokenId: Field = TokenId.default
) {
throw Error('must call Mina.setActiveInstance first');
},
getActions(
_publicKey: PublicKey,
_actionStates?: ActionStates,
Expand Down Expand Up @@ -1088,6 +1135,17 @@ async function fetchEvents(
return await activeInstance.fetchEvents(publicKey, tokenId, filterOptions);
}

/**
* @return A list of emitted sequencing actions associated to the given public key.
*/
async function fetchActions(
publicKey: PublicKey,
actionStates: ActionStates,
tokenId?: Field
) {
return await activeInstance.fetchActions(publicKey, actionStates, tokenId);
}

/**
* @return A list of emitted sequencing actions associated to the given public key.
*/
Expand Down
47 changes: 47 additions & 0 deletions src/lib/zkapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,21 @@ type ReducerReturn<Action> = {
fromActionState?: Field;
endActionState?: Field;
}): Action[][];
/**
* Fetches the list of previously emitted {@link Action}s by zkapp {@link SmartContract}.
* ```ts
* let pendingActions = await zkapp.reducer.fetchActions({
* fromActionState: actionsHash,
* });
* ```
*/
fetchActions({
fromActionState,
endActionState,
}: {
fromActionState?: Field;
endActionState?: Field;
}): Promise<Action[][]>;
};

function getReducer<A>(contract: SmartContract): ReducerReturn<A> {
Expand Down Expand Up @@ -1403,6 +1418,38 @@ Use the optional \`maxTransactionsWithActions\` argument to increase this number
);
});

return actionsForAccount;
},
async fetchActions({
fromActionState,
endActionState,
}: {
fromActionState?: Field;
endActionState?: Field;
}): Promise<A[][]> {
let actionsForAccount: A[][] = [];
let res = await Mina.fetchActions(
contract.address,
{
fromActionState,
endActionState,
},
contract.self.tokenId
);
if(res.hasOwnProperty('error')) {
throw Error(JSON.stringify(res));
}

actionsForAccount = (res as { hash: string; actions: string[][] }[]).map(
(event: { hash: string; actions: string[][] }) =>
// putting our string-Fields back into the original action type
event.actions.map((action: string[]) =>
(reducer.actionType as ProvablePure<A>).fromFields(
action.map((fieldAsString: string) => Field(fieldAsString))
)
)
);

return actionsForAccount;
},
};
Expand Down