#`Account_action_state_precondition_unsatisfied ` error when using `reducer.getActions`

6 messages · Page 1 of 1 (latest)

mortal pasture
#

I encountered an error while running on the local testnet.

The error message is: Error: [[],[["Account_action_state_precondition_unsatisfied"]]].

I suspect that the issue lies with a reducer.getActions where the endActionState parameter is not actually the last state.

Here is the relevant code snippet:

this.reducer.getActions({
  fromActionState,
  endActionState,
});

This code is part of a smart contract that have 2 main function:

@method incrementCounter(amount: Field) {
    this.reducer.dispatch(amount);
}

@method rollupIncrements(startAction: Field, endAction: Field) {
    let pendingActions = this.reducer.getActions({
      fromActionState: startAction,
      endActionState: endAction,
    });
    
    let { state: newCounter, actionState: newActionState } =
      this.reducer.reduce(
        pendingActions,
        Field,
        (state: Field, _action: Field) => {
          return state.add(_action);
        },
        { state: Field(0), actionState: startAction }
      );
    
    this.num.set(newCounter);
}
#

After calling rollupIncrements multiple times, I fetch the action state hashes and save them in an array.

for (let i = 0; i < 3; i++) {
    tx = await Mina.transaction(feePayer, () => {
      addContract.incrementCounter();
    });
    await tx.prove();
    await tx.sign([feePayerKey]).send();
}

let myActionArray: Field[] = [];
let actions = await Mina.fetchActions(addContractAddress);
if (Array.isArray(actions)) {
    for (let action of actions) {
      myActionArray.push(Field(action.hash));
    }
}

The error occurs when I send a transaction with endActionState not being the last action state.
Here is the code snippet where the error occurs:

tx = await Mina.transaction(feePayer, () => {
  addContract.rollupIncrements(
    myActionArray[0],
    myActionArray[myActionArray.length - 2]
  );
});

However, the transaction runs fine when endState is set to the last action state.

tx = await Mina.transaction(feePayer, () => {
  addContract.rollupIncrements(
    myActionArray[0],
    myActionArray[myActionArray.length - 1]
  );
});

My question is: Is this behavior intended? If not, what is the purpose of the endActionState parameter.

violet sun
#

Yes this is intended

#

The reduce() call attempts to prove that the actions you got match what has been committed to on the chain, up to the latest action

#

However, you can customize reducer() to not do this, with the skipActionStatePrecondition parameter

#

Which allows you to do something more custom including making use of the endActionsHash