Open alnoki opened 1 year ago
Note that this transaction (a package publication from a multisig account) executed successfully, but the CLI returned:
{
"Error": "API error: Unknown error error decoding response body: invalid value: map, expected map with a single key at line 1 column 3730"
}
Here, the command that prompted the error was:
aptos multisig execute \
--multisig-address $multisig_addr \
--json-file publication.json \
--private-key-file bee.key \
--max-gas 10000
Upon further investigation it was revealed that different kinds of multisig transaction executions leads to different errors.
The transaction simulator appears to still be broken for multisig transaction execution via simple entry functions, but response headers are fine. For example consider the following transaction creation:
aptos multisig create-transaction \
--multisig-address $multisig_addr \
--function-id $multisig_addr::cli_args::set_vals \
--type-args \
0x1::account::Account \
0x1::chain_id::ChainId \
--args \
u8:123 \
"bool:[false, true, false, false]" \
'address:[["0xace", "0xbee"], ["0xcad"], []]' \
--private-key-file bee.key
Once approved, a transaction execution attempt was invoked via:
aptos multisig execute \
--multisig-address $multisig_addr \
--private-key-file ace.key
This yielded the following simulation error:
{
"Error": "Simulation failed with status: Execution failed in script at code offset 0"
}
When a --max-gas
argument was specified, however, the function ran without issue and a transaction result was provided.
aptos multisig execute \
--multisig-address $multisig_addr \
--private-key-file ace.key \
--max-gas 10000
Do you want to submit transaction for a maximum of 1000000 Octas at a gas unit price of 100 Octas? [yes/no] >
y
{
"Result": {
"transaction_hash": "0xb8513449bc75d3d9df99456b55e3a0aacf01b0c85e9e6ee55392c062e6188053",
"gas_used": 3,
"gas_unit_price": 100,
"sender": "acee3447860cd5f14801badcbf69dbdb98a0c315999ded339bb9d3606ac4faa4",
"sequence_number": 5,
"success": true,
"timestamp_us": 1684676634871902,
"version": 525537197,
"vm_status": "Executed successfully"
}
}
The relevant transaction is here.
Per #7709, the PR branch adds a --json-output-file
flag to aptos move publish
, such that a package can be compiled into a public entry function JSON file in the style of #8054:
aptos move publish \
--named-addresses test_account=$multisig_addr \
--json-output-file publication.json
The resultant file looks like:
{
"function_id": "0x1::code::publish_package_txn",
"type_args": [],
"args": [
{
"arg_type": "hex",
"arg_value": "0x07436c6941726773010000000000000000403..."
},
{
"arg_type": "hex",
"arg_value": [
"0xa11ceb0b060000000b010006020608030e..."
]
}
]
}
This kind of file can be used to successfully publish a package from both a single-signer and a multisig account, as it enables a multisig owner to propose package publication from a JSON file and also to check the on-chain payload/hash. Transaction creation:
aptos multisig create-transaction \
--multisig-address $multisig_addr \
--json-file publication.json \
--hash-only \
--private-key-file ace.key
Do you want to submit a transaction for a range of [51000 - 76500] Octas at a gas unit price of 100 Octas? [yes/no] >
y
{
"Result": {
"transaction_hash": "0xfd48145327e10d5491f9e527aac362614e7b503bb4623c1260ed0b633d0fb499",
"gas_used": 510,
"gas_unit_price": 100,
"sender": "acee3447860cd5f14801badcbf69dbdb98a0c315999ded339bb9d3606ac4faa4",
"sequence_number": 6,
"success": true,
"timestamp_us": 1684677806015810,
"version": 525545673,
"vm_status": "Executed successfully"
}
}
Transaction payload/hash checking:
aptos multisig check-transaction \
--multisig-address $multisig_addr \
--json-file publication.json \
--sequence-number 4
{
"Result": {
"Status": "Transaction match",
"Multisig transaction": {
"creation_time_secs": "1684677806",
"creator": "0xacee3447860cd5f14801badcbf69dbdb98a0c315999ded339bb9d3606ac4faa4",
"payload": {
"vec": []
},
"payload_hash": {
"vec": [
"0xce31dac5c29fd54c643119b4011a4991bd96141a21be10100d75336230417e89"
]
},
"votes": {
"data": [
{
"key": "0xacee3447860cd5f14801badcbf69dbdb98a0c315999ded339bb9d3606ac4faa4",
"value": true
}
]
}
}
}
}
Once enough approvals have been made, however, the transaction simulator fails during an execution attempt if no --max-gas
argument is specified:
aptos multisig execute \
--multisig-address $multisig_addr \
--json-file publication.json \
--private-key-file bee.key
{
"Error": "API error: Unknown error error decoding response body: invalid value: map, expected map with a single key at line 1 column 10194"
}
If a --max-gas
argument is specified the transaction will execute, but it can only be successfully verified on the blockchain explorer because there is an additional API response error that prevents inspection via the CLI:
aptos multisig execute \
--multisig-address $multisig_addr \
--json-file publication.json \
--private-key-file bee.key \
--max-gas 10000
Do you want to submit transaction for a maximum of 1000000 Octas at a gas unit price of 100 Octas? [yes/no] >
y
{
"Error": "API error: Unknown error error decoding response body: invalid value: map, expected map with a single key at line 1 column 3730"
}
Note that the transaction in question was, however, successfully executed as described here
Upon further investigation, it was determined that failure modes are a result of payload/hash status:
Stored on-chain | Simulator works? | Response decoding works? |
---|---|---|
Multisig payload | No | Yes |
Multisig payload hash | No | No |
In other words, if a multisig transaction is created with a full payload stored on-chain then trying to execute the multisig transaction without specifying --max-gas
will result in an error of the form:
{
"Error": "Simulation failed with status: Execution failed in script at code offset 0"
}
The transaction can still be executed from the command line, however, and will print a successful transaction result if the payload is well-formed.
In contrast, if a multisig transaction is created with only a payload hash stored on-chain then trying to execute the multisig transaction without specifying --max-gas
will result in an error of the form:
{
"Error": "API error: Unknown error error decoding response body: invalid value: map, expected map with a single key at line 1 column 10194"
}
In this case, even though the transaction can still be executed from the command line if the payload and hash are well-formed (using --max-gas
to avoid invoking the transaction simulator), the transaction will have to be verified on the blockchain explorer because once the transaction has been executed the CLI errors out during the response decoding process:
{
"Error": "API error: Unknown error error decoding response body: invalid value: map, expected map with a single key at line 1 column 3730"
}
Thanks for reporting this and all the amazing details provided!
There are 2 types of simulation: of a non-existent multisig tx and of an existing one (explicit committed tx to create it). Currently we only support the former so you have to provide the transaction payload when running the simulation.
We'll need to add support for the latter - simulating execution of an existing multisig tx.
This issue is stale because it has been open 45 days with no activity. Remove the stale
label or comment - otherwise this will be closed in 15 days.
@movekevin @gregnazario @davidiw
Summarized findings
This issue contains substantial documentation of error testing
See this summary comment at the bottom for a simple breakdown.
Background
This bug was uncovered while working on a PR to extend multisig support for the
aptos
CLI.Once a multisig transaction was approved on-chain with enough votes, it could only be executed by specifying a
--max-gas
argument to the CLIexecute
subcommand, as this approach avoids calling the transaction simulator during this inner call.Error messages
The relevant error thrown as a result of the simulator is:
After tracing through the stack, it appears there is some kind of request response deserialization error here
Successful transaction
The successful transaction is question is here, for this multisig account, run with this command on the CLI:
Note the
--max-gas
argument for the modified CLIexecute
subcommand.