From 8b32e9f88fe4d8dd21eadbdbb54b0276d6fd1506 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Thu, 27 May 2021 14:46:19 -0700 Subject: [PATCH 01/48] wip debug locally with testnet state doc --- docs/develop/contracts/debug-locally.md | 54 +++++++++++++++++++++++++ website/sidebars.json | 1 + 2 files changed, 55 insertions(+) create mode 100644 docs/develop/contracts/debug-locally.md diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md new file mode 100644 index 00000000000..04f7fb55e41 --- /dev/null +++ b/docs/develop/contracts/debug-locally.md @@ -0,0 +1,54 @@ +--- +id: debug-locally +title: Debug Testnet or Mainnet Contract Locally +sidebar_label: Debug Locally +--- + +After contracts are deployed on testnet or mainnet, you might still experience corner case of: + +- contract execution logic does not happen in expected way; +- storage usage is higher than expected; +- gas cost is higher than expected. + +In these cases, you may want to capture the contract state and function call arguments to debug in the local sandbox. You'll make incremental changes, test locally until everything works as expected. You will also likely want to keep the test fixtures to avoid regression in future. + +## Obtain States and Other Parameters from Testnet/Mainnet + +The following things determined the contract call results: + +- Contract code and state; +- Node's genesis config; +- Context data when the transaction happens, like current epoch, block height, etc; +- Caller (signer) of the transaction and arguments. + +We'll need to obtain all these information to reproduce the contract call locally. + +### Contract Code and State + +You most likely already have the contract code you've deployed. But in case you don't, you can fetch it by `query` RPC: + +``` +curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_code","block_id": block-height-or-hash,"account_id":"contract-account"}}' +``` + +You can also replace the url to `https://rpc.mainnet.near.org` to fetch code from mainnet. This is same for all following RPC requests in this article. + +For contract state, there's a few ways of getting it. If your contract state is less than 50Kib, you can fetch it with `query` RPC: + +``` +curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_state","block_id":block-height-or-hash,"account_id":"contract-account","prefix_base64":""}}' +``` + +Otherwise, you need to run a testnet or mainnet node with `nearup`, and wait it fully synced. Then you can either use `state-viewer` to aggreggate entire state to a new genesis, or use `state-viewer` to export state from only specified contracts. + +### Node's Genesis Config + +This can be obtained by [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config) + +### Context Data when Execute the Contract + +This can be found by inspect the transaction information on Explorer. This should be combined with the above two sections to form a new genesis. We're going to build a tool to automate this process. For now we'll just manually edit genesis config. + +### Caller of the Transaction and Arguments. + +You'll also found them in explorer. If you do not control keys of the transaction caller (signer), you can use the patch_state API to add your public key to account. diff --git a/website/sidebars.json b/website/sidebars.json index 6dbde8cb28c..d2e57514077 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -37,6 +37,7 @@ ], "Smart Contracts": [ "develop/contracts/overview", + "develop/contracts/debug-locally", { "type": "subcategory", "label": "AssemblyScript", From c1779f7c8a12ace05cf2b020a8ebcea9c072444d Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Thu, 27 May 2021 16:17:54 -0700 Subject: [PATCH 02/48] intructions on getting all required information to reproduce a transaction --- docs/develop/contracts/debug-locally.md | 33 +++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 04f7fb55e41..77fbdcc88dc 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -18,14 +18,27 @@ The following things determined the contract call results: - Contract code and state; - Node's genesis config; -- Context data when the transaction happens, like current epoch, block height, etc; +- Context data when the transaction happens, like current epoch, block height, gas price etc; - Caller (signer) of the transaction and arguments. -We'll need to obtain all these information to reproduce the contract call locally. +We'll need to obtain all this information to reproduce the contract call locally. This information can be divide into three categories, each of them is configured in a different way: -### Contract Code and State +- Genesis config +- State records +- Parameter provided when sending transaction -You most likely already have the contract code you've deployed. But in case you don't, you can fetch it by `query` RPC: +### Genesis config + +The context data when transaction happens, like current epoch, block height, gas price etc. and testnet/mainnet specific configuration such as block time, gas amount for different kind of actions all come into this category. This parameters can only be set by start a local sandbox node from a modified version of genesis file. +First thing you need is fetch testnet/mainnet genesis config. This can be obtained by [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use response file to replace sandbox's genesis.json. Now we have the same configuration as the testnet/mainnet in sandbox. But there's still something different: protocol version, block height and block timestamp. This is because genesis indicates the start of the most recent hard fork of testnet/mainnet, but many blocks and time has passed since the genesis. There's also protocol version upgrades since genesis. If your contract logic doesn't depend on these parameters replay contract method on such parameters, sandbox node should give you accurate logic, gas and storage simulation. However if you do require info like certain epoch and block height, you can modify `"genesis_height"`, `"protocol_version"` on genesis.json. + +Change `"genesis_time"` won't have effect. There's going to be a time travel RPC for you to tweak block timestamps. Also note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More common you want to depend on how many blocks or times have passed, that's a relative number. And you may want to base on the parameters at the time block produced, such as validator set, protocol feature availability etc., these are tied to epoch rather than block, so you don't have to strictly depend on a given block number. + +### State Records + +Every state stored on NEAR Blockchain including contract code, contract states, accounts, access keys are in the form of state records. To run a node having equivalent state as a testnet/mainnet node you need to apply same state records as the testnet/mainnet. You don't need to apply all states which is many gigabytes, but only those contract code/state and account keys that were used in the transaction. Once you have these state records, you can apply them by either place them in the `"records"` section of genesis before starting sandbox, or use `sandbox_patch_state` RPC to add them dynamically after starting sandbox. Let's see how state records can be obtained: + +For contract code, Most likely you already have the contract code you've deployed. But in case you don't, you can fetch it by `query` RPC: ``` curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_code","block_id": block-height-or-hash,"account_id":"contract-account"}}' @@ -41,14 +54,8 @@ curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"json Otherwise, you need to run a testnet or mainnet node with `nearup`, and wait it fully synced. Then you can either use `state-viewer` to aggreggate entire state to a new genesis, or use `state-viewer` to export state from only specified contracts. -### Node's Genesis Config - -This can be obtained by [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config) - -### Context Data when Execute the Contract - -This can be found by inspect the transaction information on Explorer. This should be combined with the above two sections to form a new genesis. We're going to build a tool to automate this process. For now we'll just manually edit genesis config. +For account and access key, you can use [view account](https://docs.near.org/docs/api/rpc#view-account) and [view access keys](https://docs.near.org/docs/api/rpc#view-access-key-list) RPCs, respectively. -### Caller of the Transaction and Arguments. +### Parameter provided when sending transaction -You'll also found them in explorer. If you do not control keys of the transaction caller (signer), you can use the patch_state API to add your public key to account. +This can be found by inspect the transaction information on Explorer. This is majorly the function call arguments, gas attached, deposit attached and the signer of the transaction. If you do not control keys of the transaction caller (signer), you can use the patch_state RPC to add your public key to account. From 11281e1eed322e29da076deeea8368adeee2d938 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:12:13 -0700 Subject: [PATCH 03/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 77fbdcc88dc..e6fa731411d 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -4,7 +4,7 @@ title: Debug Testnet or Mainnet Contract Locally sidebar_label: Debug Locally --- -After contracts are deployed on testnet or mainnet, you might still experience corner case of: +After contracts are deployed on `testnet` or `mainnet` you might still experience corner case of: - contract execution logic does not happen in expected way; - storage usage is higher than expected; From b71413cc7f801a05ef3ca164db1516b663c2cfb3 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:12:20 -0700 Subject: [PATCH 04/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index e6fa731411d..1e9376038f8 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -6,9 +6,9 @@ sidebar_label: Debug Locally After contracts are deployed on `testnet` or `mainnet` you might still experience corner case of: -- contract execution logic does not happen in expected way; -- storage usage is higher than expected; -- gas cost is higher than expected. +- Contract execution logic does not happen in the expected way. +- Storage usage is higher than expected. +- Gas cost is higher than expected. In these cases, you may want to capture the contract state and function call arguments to debug in the local sandbox. You'll make incremental changes, test locally until everything works as expected. You will also likely want to keep the test fixtures to avoid regression in future. From 780a5161fb47cc0e46cc5517bc853c4f60981b88 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:12:36 -0700 Subject: [PATCH 05/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 1e9376038f8..f91200bba11 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -10,7 +10,7 @@ After contracts are deployed on `testnet` or `mainnet` you might still experienc - Storage usage is higher than expected. - Gas cost is higher than expected. -In these cases, you may want to capture the contract state and function call arguments to debug in the local sandbox. You'll make incremental changes, test locally until everything works as expected. You will also likely want to keep the test fixtures to avoid regression in future. +In these cases you may want to capture the contract state and function call arguments to debug in the local sandbox. You'll make incremental changes and test locally until everything works as expected. You will also likely want to keep the test fixtures to avoid regression in future. ## Obtain States and Other Parameters from Testnet/Mainnet From c7cde15f10860326179e825429cbbfe1458df48c Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:12:43 -0700 Subject: [PATCH 06/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index f91200bba11..9e4595e1b50 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -14,7 +14,7 @@ In these cases you may want to capture the contract state and function call argu ## Obtain States and Other Parameters from Testnet/Mainnet -The following things determined the contract call results: +The following things determine the contract call results: - Contract code and state; - Node's genesis config; From 5db46afd9e2cef617a81f7f1da78fcd55c856c10 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:12:50 -0700 Subject: [PATCH 07/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 9e4595e1b50..69317e8200e 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -16,9 +16,9 @@ In these cases you may want to capture the contract state and function call argu The following things determine the contract call results: -- Contract code and state; -- Node's genesis config; -- Context data when the transaction happens, like current epoch, block height, gas price etc; +- Contract code and state. +- Node's genesis config. +- Context data when the transaction happens like current epoch, block height, gas price, etc. - Caller (signer) of the transaction and arguments. We'll need to obtain all this information to reproduce the contract call locally. This information can be divide into three categories, each of them is configured in a different way: From 52ee6aab3bcf8191cafdc6a63fc6eb6aa18df9ca Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:13:01 -0700 Subject: [PATCH 08/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 69317e8200e..7ea4e2911d0 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -44,7 +44,7 @@ For contract code, Most likely you already have the contract code you've deploye curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_code","block_id": block-height-or-hash,"account_id":"contract-account"}}' ``` -You can also replace the url to `https://rpc.mainnet.near.org` to fetch code from mainnet. This is same for all following RPC requests in this article. +You can also replace the url to `https://rpc.mainnet.near.org` to fetch code from `mainnet`. This is same for all following RPC requests in this article. For contract state, there's a few ways of getting it. If your contract state is less than 50Kib, you can fetch it with `query` RPC: From cef1ae87924b4483a17187466fd9c7430f53ba48 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:13:12 -0700 Subject: [PATCH 09/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 7ea4e2911d0..a8a343c3941 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -21,7 +21,7 @@ The following things determine the contract call results: - Context data when the transaction happens like current epoch, block height, gas price, etc. - Caller (signer) of the transaction and arguments. -We'll need to obtain all this information to reproduce the contract call locally. This information can be divide into three categories, each of them is configured in a different way: +We'll need to obtain all this information to reproduce the contract call locally. This information can be divided into three categories, each of which is configured differently: - Genesis config - State records From 004bc4a9cc40be469c3a6680214d5ea608fe794f Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:13:27 -0700 Subject: [PATCH 10/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index a8a343c3941..56940519b41 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -46,7 +46,9 @@ curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"json You can also replace the url to `https://rpc.mainnet.near.org` to fetch code from `mainnet`. This is same for all following RPC requests in this article. -For contract state, there's a few ways of getting it. If your contract state is less than 50Kib, you can fetch it with `query` RPC: +**Contract state:** + +There are a few ways of getting contract state. If your contract state is less than 50Kib you can fetch it with `query` RPC: ``` curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_state","block_id":block-height-or-hash,"account_id":"contract-account","prefix_base64":""}}' From d6429872c7b7fa3049b724bdb8fff28916488b1a Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:13:34 -0700 Subject: [PATCH 11/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 56940519b41..97c8a7b08fa 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -54,7 +54,7 @@ There are a few ways of getting contract state. If your contract state is less t curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_state","block_id":block-height-or-hash,"account_id":"contract-account","prefix_base64":""}}' ``` -Otherwise, you need to run a testnet or mainnet node with `nearup`, and wait it fully synced. Then you can either use `state-viewer` to aggreggate entire state to a new genesis, or use `state-viewer` to export state from only specified contracts. +Otherwise, you need to run a `testnet` or `mainnet` node with `nearup` and wait for it fully synced. Then you can either use `state-viewer` to aggregate the entire state to a new genesis or use `state-viewer` to export the state from only specified contracts. For account and access key, you can use [view account](https://docs.near.org/docs/api/rpc#view-account) and [view access keys](https://docs.near.org/docs/api/rpc#view-access-key-list) RPCs, respectively. From 21c2fb333772b4c3268dccd8018b4e1a51220a48 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:13:40 -0700 Subject: [PATCH 12/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 97c8a7b08fa..07647471aeb 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -56,6 +56,8 @@ curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"json Otherwise, you need to run a `testnet` or `mainnet` node with `nearup` and wait for it fully synced. Then you can either use `state-viewer` to aggregate the entire state to a new genesis or use `state-viewer` to export the state from only specified contracts. +**Account and Access Key:** + For account and access key, you can use [view account](https://docs.near.org/docs/api/rpc#view-account) and [view access keys](https://docs.near.org/docs/api/rpc#view-access-key-list) RPCs, respectively. ### Parameter provided when sending transaction From 4e8963368c3242476630d4c67a377b62b0ed7d37 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 12:13:49 -0700 Subject: [PATCH 13/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 07647471aeb..485ce535a24 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -62,4 +62,4 @@ For account and access key, you can use [view account](https://docs.near.org/doc ### Parameter provided when sending transaction -This can be found by inspect the transaction information on Explorer. This is majorly the function call arguments, gas attached, deposit attached and the signer of the transaction. If you do not control keys of the transaction caller (signer), you can use the patch_state RPC to add your public key to account. +This can be found by inspecting the transaction information on [NEAR Explorer](/docs/tools/near-explorer). This is majorly the function call arguments, gas attached, deposit attached, and the signer of the transaction. If you do not control the keys of the transaction caller (signer) you can use the `patch_state` RPC to add your public key to the account. From dc37c4c9386d3844552411decf2280ac35e53f81 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:10:03 -0700 Subject: [PATCH 14/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 485ce535a24..ad2ee536caa 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -23,9 +23,9 @@ The following things determine the contract call results: We'll need to obtain all this information to reproduce the contract call locally. This information can be divided into three categories, each of which is configured differently: -- Genesis config -- State records -- Parameter provided when sending transaction +1. Genesis config +2. State records +3. Parameter provided when sending transaction ### Genesis config From 5a7f667e33465453dc61dbb0253bcc4f652aea5b Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:10:20 -0700 Subject: [PATCH 15/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index ad2ee536caa..3c31fd56398 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -29,7 +29,7 @@ We'll need to obtain all this information to reproduce the contract call locally ### Genesis config -The context data when transaction happens, like current epoch, block height, gas price etc. and testnet/mainnet specific configuration such as block time, gas amount for different kind of actions all come into this category. This parameters can only be set by start a local sandbox node from a modified version of genesis file. +The context data when a transaction happens such as the current epoch, block height, gas price, etc., as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions) are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. First thing you need is fetch testnet/mainnet genesis config. This can be obtained by [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use response file to replace sandbox's genesis.json. Now we have the same configuration as the testnet/mainnet in sandbox. But there's still something different: protocol version, block height and block timestamp. This is because genesis indicates the start of the most recent hard fork of testnet/mainnet, but many blocks and time has passed since the genesis. There's also protocol version upgrades since genesis. If your contract logic doesn't depend on these parameters replay contract method on such parameters, sandbox node should give you accurate logic, gas and storage simulation. However if you do require info like certain epoch and block height, you can modify `"genesis_height"`, `"protocol_version"` on genesis.json. Change `"genesis_time"` won't have effect. There's going to be a time travel RPC for you to tweak block timestamps. Also note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More common you want to depend on how many blocks or times have passed, that's a relative number. And you may want to base on the parameters at the time block produced, such as validator set, protocol feature availability etc., these are tied to epoch rather than block, so you don't have to strictly depend on a given block number. From 8f291370d5ded72422215a9dd527182943dcacb3 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:10:54 -0700 Subject: [PATCH 16/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 3c31fd56398..ea1f692e49e 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -30,7 +30,7 @@ We'll need to obtain all this information to reproduce the contract call locally ### Genesis config The context data when a transaction happens such as the current epoch, block height, gas price, etc., as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions) are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. -First thing you need is fetch testnet/mainnet genesis config. This can be obtained by [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use response file to replace sandbox's genesis.json. Now we have the same configuration as the testnet/mainnet in sandbox. But there's still something different: protocol version, block height and block timestamp. This is because genesis indicates the start of the most recent hard fork of testnet/mainnet, but many blocks and time has passed since the genesis. There's also protocol version upgrades since genesis. If your contract logic doesn't depend on these parameters replay contract method on such parameters, sandbox node should give you accurate logic, gas and storage simulation. However if you do require info like certain epoch and block height, you can modify `"genesis_height"`, `"protocol_version"` on genesis.json. +The first thing you'll need to do is fetch the `testnet`/`mainnet` genesis config. This can be obtained by the [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use the response file to replace the sandbox's `genesis.json`. Once complete, you will have the same configuration as `testnet`/`mainnet` in the sandbox aside from the protocol version, block height, and block timestamp. This is because genesis indicates the start of the most recent hard fork of `testnet`/`mainnet` but many blocks have been produced, protocol versions released, and time has passed the blockchain genesis. If your contract logic doesn't depend on these parameters the sandbox node should give you accurate logic, gas, and storage simulation. However, if you do require info like certain epoch and block height details you can modify `"genesis_height"` and `"protocol_version"` on your `genesis.json` file. Change `"genesis_time"` won't have effect. There's going to be a time travel RPC for you to tweak block timestamps. Also note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More common you want to depend on how many blocks or times have passed, that's a relative number. And you may want to base on the parameters at the time block produced, such as validator set, protocol feature availability etc., these are tied to epoch rather than block, so you don't have to strictly depend on a given block number. From 601efb6a49e909b53c26a2731bb0fa2c9dcdc4ae Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:11:30 -0700 Subject: [PATCH 17/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index ea1f692e49e..40b39dd6a62 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -32,7 +32,7 @@ We'll need to obtain all this information to reproduce the contract call locally The context data when a transaction happens such as the current epoch, block height, gas price, etc., as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions) are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. The first thing you'll need to do is fetch the `testnet`/`mainnet` genesis config. This can be obtained by the [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use the response file to replace the sandbox's `genesis.json`. Once complete, you will have the same configuration as `testnet`/`mainnet` in the sandbox aside from the protocol version, block height, and block timestamp. This is because genesis indicates the start of the most recent hard fork of `testnet`/`mainnet` but many blocks have been produced, protocol versions released, and time has passed the blockchain genesis. If your contract logic doesn't depend on these parameters the sandbox node should give you accurate logic, gas, and storage simulation. However, if you do require info like certain epoch and block height details you can modify `"genesis_height"` and `"protocol_version"` on your `genesis.json` file. -Change `"genesis_time"` won't have effect. There's going to be a time travel RPC for you to tweak block timestamps. Also note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More common you want to depend on how many blocks or times have passed, that's a relative number. And you may want to base on the parameters at the time block produced, such as validator set, protocol feature availability etc., these are tied to epoch rather than block, so you don't have to strictly depend on a given block number. +Simply changing `"genesis_time"` won't have an effect. In addition, there's going to be a time travel RPC for you to tweak block timestamps. Also, note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More commonly, you most likely want to depend on how many blocks or how much time has passed. This is a relative number and you may want to base on the parameters at the time the block was produced, such as a validator set, protocol feature availability, etc. These are tied to [epoch](/docs/concepts/epoch) rather than the individual block so you don't have to strictly depend on a given block number. ### State Records From 8349b38c1c7a4b1366c289d848a96eb215e24f8d Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:12:03 -0700 Subject: [PATCH 18/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 40b39dd6a62..3b253ebc606 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -36,7 +36,7 @@ Simply changing `"genesis_time"` won't have an effect. In addition, there's goin ### State Records -Every state stored on NEAR Blockchain including contract code, contract states, accounts, access keys are in the form of state records. To run a node having equivalent state as a testnet/mainnet node you need to apply same state records as the testnet/mainnet. You don't need to apply all states which is many gigabytes, but only those contract code/state and account keys that were used in the transaction. Once you have these state records, you can apply them by either place them in the `"records"` section of genesis before starting sandbox, or use `sandbox_patch_state` RPC to add them dynamically after starting sandbox. Let's see how state records can be obtained: +Every state stored on the NEAR Blockchain including contract code, contract states, accounts, and access keys is in the form of state records. To run a node having an equivalent state as a `testnet`/`mainnet` node you need to apply the same state records as `testnet`/`mainnet`. You don't need to apply all states which can be many gigabytes but only those contract code/state and account keys that were used in the transaction. Once you have these state records you can apply them by either placing them in the `"records"` section of genesis _before_ starting the sandbox or use `sandbox_patch_state` RPC to add them dynamically _after_ starting the sandbox. Let's see how these state records can be obtained: For contract code, Most likely you already have the contract code you've deployed. But in case you don't, you can fetch it by `query` RPC: From cbfbc6c53bcd98d23cd7129c3cddd5df481dbaa2 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:12:25 -0700 Subject: [PATCH 19/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 3b253ebc606..5a22c4757bd 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -38,7 +38,9 @@ Simply changing `"genesis_time"` won't have an effect. In addition, there's goin Every state stored on the NEAR Blockchain including contract code, contract states, accounts, and access keys is in the form of state records. To run a node having an equivalent state as a `testnet`/`mainnet` node you need to apply the same state records as `testnet`/`mainnet`. You don't need to apply all states which can be many gigabytes but only those contract code/state and account keys that were used in the transaction. Once you have these state records you can apply them by either placing them in the `"records"` section of genesis _before_ starting the sandbox or use `sandbox_patch_state` RPC to add them dynamically _after_ starting the sandbox. Let's see how these state records can be obtained: -For contract code, Most likely you already have the contract code you've deployed. But in case you don't, you can fetch it by `query` RPC: +**Contract code:** + +Most likely you already have the contract code you've deployed but in case you don't you can fetch it by `query` RPC: ``` curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_code","block_id": block-height-or-hash,"account_id":"contract-account"}}' From ee93af0c15d79d5208190c6baca2bebe358382b7 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:13:05 -0700 Subject: [PATCH 20/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 5a22c4757bd..4c85e79988b 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -60,6 +60,8 @@ Otherwise, you need to run a `testnet` or `mainnet` node with `nearup` and wait **Account and Access Key:** +**Account and Access Key:** + For account and access key, you can use [view account](https://docs.near.org/docs/api/rpc#view-account) and [view access keys](https://docs.near.org/docs/api/rpc#view-access-key-list) RPCs, respectively. ### Parameter provided when sending transaction From 91f8bfa328d7593d92fe80cefd4813fd0b19c299 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 28 May 2021 16:15:19 -0700 Subject: [PATCH 21/48] remove a duplicate caused by ithub commit suggestion --- docs/develop/contracts/debug-locally.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 4c85e79988b..829c03ecb5c 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -38,7 +38,7 @@ Simply changing `"genesis_time"` won't have an effect. In addition, there's goin Every state stored on the NEAR Blockchain including contract code, contract states, accounts, and access keys is in the form of state records. To run a node having an equivalent state as a `testnet`/`mainnet` node you need to apply the same state records as `testnet`/`mainnet`. You don't need to apply all states which can be many gigabytes but only those contract code/state and account keys that were used in the transaction. Once you have these state records you can apply them by either placing them in the `"records"` section of genesis _before_ starting the sandbox or use `sandbox_patch_state` RPC to add them dynamically _after_ starting the sandbox. Let's see how these state records can be obtained: -**Contract code:** +**Contract code:** Most likely you already have the contract code you've deployed but in case you don't you can fetch it by `query` RPC: @@ -48,7 +48,7 @@ curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"json You can also replace the url to `https://rpc.mainnet.near.org` to fetch code from `mainnet`. This is same for all following RPC requests in this article. -**Contract state:** +**Contract state:** There are a few ways of getting contract state. If your contract state is less than 50Kib you can fetch it with `query` RPC: @@ -60,8 +60,6 @@ Otherwise, you need to run a `testnet` or `mainnet` node with `nearup` and wait **Account and Access Key:** -**Account and Access Key:** - For account and access key, you can use [view account](https://docs.near.org/docs/api/rpc#view-account) and [view access keys](https://docs.near.org/docs/api/rpc#view-access-key-list) RPCs, respectively. ### Parameter provided when sending transaction From e149cdb99bc41bb16b230539f88f9eebc38f0085 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Tue, 15 Jun 2021 14:14:31 +0800 Subject: [PATCH 22/48] document to use automatic script to fetch info for reproduce --- docs/develop/contracts/debug-locally.md | 46 +++++++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 829c03ecb5c..a8482aaa605 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -6,22 +6,54 @@ sidebar_label: Debug Locally After contracts are deployed on `testnet` or `mainnet` you might still experience corner case of: -- Contract execution logic does not happen in the expected way. +- Contract execution logic does not happen expectedly. - Storage usage is higher than expected. - Gas cost is higher than expected. -In these cases you may want to capture the contract state and function call arguments to debug in the local sandbox. You'll make incremental changes and test locally until everything works as expected. You will also likely want to keep the test fixtures to avoid regression in future. - -## Obtain States and Other Parameters from Testnet/Mainnet +In these cases, you may want to capture the contract state and function call arguments to debug in the local sandbox. You'll make incremental changes and test locally until everything works as expected. You will also likely want to keep the test fixtures to avoid regression in future. The following things determine the contract call results: - Contract code and state. - Node's genesis config. -- Context data when the transaction happens like current epoch, block height, gas price, etc. +- Context data when the transaction happens like the current epoch, block height, gas price, etc. - Caller (signer) of the transaction and arguments. -We'll need to obtain all this information to reproduce the contract call locally. This information can be divided into three categories, each of which is configured differently: +Except for the caller and arguments, which you already know other three information. If you don't, for example, in the case of a third party contract calling into your account, then you can find arguments from [NEAR explorer](https://explorer.testnet.near.org). The first three pieces of information are all related to the blockchain state when the transaction happened. Therefore, a "snapshot" of blockchain has to be captured to obtain this information and load it into the near sandbox. You can either load them automatically with a script or manually if you're interested to know every aspect of how a transaction is affected by blockchain status. + +## Obtain Information from Testnet/Mainnet automatically + +First clone the repro script repo and install dependency: + +```bash +git clone https://github.com/near/repro-near-funcall.git +cd repro-near-funcall +npm i +``` + +To fetch the transaction in problem, you need to provide a few things: + +- Sandbox node's home directory, which you were used to spin up the local sandbox node. +- Accounts and contract accounts that were used during the transaction. +- If it's on mainnet, the mainnet rpc URL. + +For example: + +```bash +node get-sandbox-repro-genesis.js \ + -c contract1 -c contract2 \ + -a account1 -a account2 -a account3 \ + -s /tmp/near-sandbox + -u https://rpc.mainnet.near.org +``` + +This script will fetch account, contract, and blockchain state and generate and synthesize the genesis file replacing the current sandbox's genesis file. The old genesis file will be backed up as `genesis.json.bak`. You can now simply start the sandbox node as before, and it has accounts and contracts state loaded. Just send the transaction with `near-cli` or write a test, and you'll see the reproduced transaction executed on the sandbox node. + +## Obtain Information from Testnet/Mainnet Manually + +Usually use the above script to fetch all information to reproduce is the most effortless way. But if you want to know every detail on how transaction execution is affected by the status of blockchain, you can follow this section to fetch the information manually. + +The information we needed can be divided into three categories, each of which is configured differently: 1. Genesis config 2. State records @@ -32,7 +64,7 @@ We'll need to obtain all this information to reproduce the contract call locally The context data when a transaction happens such as the current epoch, block height, gas price, etc., as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions) are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. The first thing you'll need to do is fetch the `testnet`/`mainnet` genesis config. This can be obtained by the [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use the response file to replace the sandbox's `genesis.json`. Once complete, you will have the same configuration as `testnet`/`mainnet` in the sandbox aside from the protocol version, block height, and block timestamp. This is because genesis indicates the start of the most recent hard fork of `testnet`/`mainnet` but many blocks have been produced, protocol versions released, and time has passed the blockchain genesis. If your contract logic doesn't depend on these parameters the sandbox node should give you accurate logic, gas, and storage simulation. However, if you do require info like certain epoch and block height details you can modify `"genesis_height"` and `"protocol_version"` on your `genesis.json` file. -Simply changing `"genesis_time"` won't have an effect. In addition, there's going to be a time travel RPC for you to tweak block timestamps. Also, note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More commonly, you most likely want to depend on how many blocks or how much time has passed. This is a relative number and you may want to base on the parameters at the time the block was produced, such as a validator set, protocol feature availability, etc. These are tied to [epoch](/docs/concepts/epoch) rather than the individual block so you don't have to strictly depend on a given block number. +Simply changing `"genesis_time"` won't affect. In addition, there's going to be a time travel RPC for you to tweak block timestamps. Also, note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More commonly, you most likely want to depend on how many blocks or how much time has passed. This is a relative number and you may want to base on the parameters at the time the block was produced, such as a validator set, protocol feature availability, etc. These are tied to [epoch](/docs/concepts/epoch) rather than the individual block so you don't have to strictly depend on a given block number. ### State Records From 82f7a570dcdd136087f39afd282da20c9a9d1445 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Tue, 15 Jun 2021 16:18:03 +0800 Subject: [PATCH 23/48] automatic script to generate genesis for sandbox and example usage --- docs/develop/contracts/debug-locally.md | 85 ++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index a8482aaa605..ae81ffc3461 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -36,6 +36,7 @@ To fetch the transaction in problem, you need to provide a few things: - Sandbox node's home directory, which you were used to spin up the local sandbox node. - Accounts and contract accounts that were used during the transaction. - If it's on mainnet, the mainnet rpc URL. +- Block number or hash before the transaction to reproduce happened. This tool fetches the latest state if not given, which might not be the state you want if this transaction has mutated the blockchain state. For example: @@ -43,12 +44,90 @@ For example: node get-sandbox-repro-genesis.js \ -c contract1 -c contract2 \ -a account1 -a account2 -a account3 \ - -s /tmp/near-sandbox - -u https://rpc.mainnet.near.org + -s /tmp/near-sandbox \ + -u https://rpc.mainnet.near.org \ + -b 123456 ``` This script will fetch account, contract, and blockchain state and generate and synthesize the genesis file replacing the current sandbox's genesis file. The old genesis file will be backed up as `genesis.json.bak`. You can now simply start the sandbox node as before, and it has accounts and contracts state loaded. Just send the transaction with `near-cli` or write a test, and you'll see the reproduced transaction executed on the sandbox node. +### Real World Example to Reproduce a Cross Contract Call Example On Test Net + +Let's see the whole picture of reproducing a real-world transaction from testnet. Assume we have two contracts. The `simple-state` contract has a `set_status` method which stores a string for the signer of the transaction. The `cross-contract` contract has a `set_in_other_contract` which simply forwards the string to `simple-state` contract and calls it's `set_status` method. You can see this is almost the simplest case of a cross contract call situation and we'll use this example to demostrate how to reproduce it locally with the sandbox node. + +#### Preparation + +First let's deploy the contracts and have some transaction to reproduce on the testnet. Go to the `repro-near-funcall` repo we just cloned. Run these commands to create testnet accounts, deploy contracts and submit a transaction: + +```bash +# Replace with your testnet account +export REPRO_ACCOUNT=your-testnet-account.testnet + +# Create subaccount and deploy contracts +near create-account simple-state.$REPRO_ACCOUNT --initialBalance 10 --masterAccount $REPRO_ACCOUNT +near deploy --accountId simple-state.$REPRO_ACCOUNT --wasmFile res/simple_state.wasm +near create-account cross-contract.$REPRO_ACCOUNT --initialBalance 10 --masterAccount $REPRO_ACCOUNT +near deploy --accountId cross-contract.$REPRO_ACCOUNT --wasmFile res/cross_contract.wasm --initFunction new --initArgs "{\"state_contract\":\"simple-state.$REPRO_ACCOUNT\"}" + +# Set some state so we can verify the state fetched matches it on testnet +near call simple-state.$REPRO_ACCOUNT set_status --accountId $REPRO_ACCOUNT '{"message":"hello"}' +``` + +Now let's try to view the status string set on testnet: + +```bash +near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT +``` + +You can see the message has been set to "hello". It'll also show a link to explorer, and in the exploer page displays block hash that this view status happened, let's export it to a shell variable as well: + +```bash +# Replace with your block hash +export BLOCK=9pNq7bJ2WkYDuGT94x6Hh6jPPer5TC3Qh2dDbon5iPNz +``` + +It's time to run the transaction on testnet, which we're going to reproduce shortly: + +```bash +near call cross-contract.$REPRO_ACCOUNT set_in_other_contract --accountId $REPRO_ACCOUNT '{"message":"world"}' +``` + +After this transaction is done, the status of `$REPRO_ACCOUNT` should be set to "world". You can verify this by calling above `get_status` method again. + +#### Fetch Information and Reproduce Locally + +We can now move to reproduce this cross contract call locally. + +1. Spin up a sandbox node follow [this guide](https://docs.near.org/docs/develop/contracts/sandbox). Don't start the sandbox node yet. +2. Run the `get-sandbox-repro-genesis` tool to fetch information. Assume you have sandbox node's home dir in /tmp/near-sandbox. + +```bash +node get-sandbox-repro-genesis.js \ + -c simple-state.$REPRO_ACCOUNT -c cross-contract.$REPRO_ACCOUNT \ + -a $REPRO_ACCOUNT \ + -b $BLOCK \ + -s /tmp/near-sandbox \ + -u https://rpc.testnet.near.org +``` + +3. Run sandbox node +4. Copy the `$REPRO_ACCOUNT` key from `~/.near-credentials/testnet/$REPRO_ACCOUNT.json` to `~/.near-credentials/local/`. +5. Check the status is now "hello" in sandbox: + +``` +export NEAR_ENV=local +near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT +``` + +6. Finally we can reproduce the testnet cross transaction: + +``` +near call cross-contract.$REPRO_ACCOUNT set_in_other_contract --accountId $REPRO_ACCOUNT '{"message":"world"}' +near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT +``` + +You'll see the status has been successfully set to "world". If you're debugging a contract bug and want to avoid regression in future, it's recommended to keep the genesis generated by `get-sandbox0repro-genesis.js` as a fixture and write a test script to run the transaction on sandbox node. You can refer to [this doc](https://docs.near.org/docs/develop/contracts/sandbox) about writing sandbox test script. + ## Obtain Information from Testnet/Mainnet Manually Usually use the above script to fetch all information to reproduce is the most effortless way. But if you want to know every detail on how transaction execution is affected by the status of blockchain, you can follow this section to fetch the information manually. @@ -72,7 +151,7 @@ Every state stored on the NEAR Blockchain including contract code, contract stat **Contract code:** -Most likely you already have the contract code you've deployed but in case you don't you can fetch it by `query` RPC: +Most likely, you already have the contract code you've deployed but in case you don't you can fetch it by `query` RPC: ``` curl https://rpc.testnet.near.org -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":1, "method":"query", "params":{"request_type":"view_code","block_id": block-height-or-hash,"account_id":"contract-account"}}' From 45b1cab537e6ad2b60203ef41ae985022df546aa Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:52:55 +0800 Subject: [PATCH 24/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index ae81ffc3461..3bfea7d0547 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -4,7 +4,7 @@ title: Debug Testnet or Mainnet Contract Locally sidebar_label: Debug Locally --- -After contracts are deployed on `testnet` or `mainnet` you might still experience corner case of: +After contracts are deployed on `testnet` or `mainnet` you might still experience one of the following corner cases: - Contract execution logic does not happen expectedly. - Storage usage is higher than expected. From b48c1b4c2389ef0b668ad1bdf3ad0422397fcc45 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:53:08 +0800 Subject: [PATCH 25/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 3bfea7d0547..83f0c25ab62 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -12,14 +12,14 @@ After contracts are deployed on `testnet` or `mainnet` you might still experienc In these cases, you may want to capture the contract state and function call arguments to debug in the local sandbox. You'll make incremental changes and test locally until everything works as expected. You will also likely want to keep the test fixtures to avoid regression in future. -The following things determine the contract call results: +Except for the contract caller and arguments passed, the following things determine the contract call results: - Contract code and state. - Node's genesis config. - Context data when the transaction happens like the current epoch, block height, gas price, etc. - Caller (signer) of the transaction and arguments. -Except for the caller and arguments, which you already know other three information. If you don't, for example, in the case of a third party contract calling into your account, then you can find arguments from [NEAR explorer](https://explorer.testnet.near.org). The first three pieces of information are all related to the blockchain state when the transaction happened. Therefore, a "snapshot" of blockchain has to be captured to obtain this information and load it into the near sandbox. You can either load them automatically with a script or manually if you're interested to know every aspect of how a transaction is affected by blockchain status. +If you do not have the contract caller or args (Ex. A third party contract calling your account) then you can find the arguments from [NEAR Explorer](https://explorer.testnet.near.org). The first three pieces of information are all related to the blockchain state when the transaction happened. Therefore, a "snapshot" of blockchain has to be captured to obtain this information and load it into the NEAR Sandbox. You can either load them automatically with a script or manually if you're interested to know every aspect of how a transaction is affected by blockchain status. ## Obtain Information from Testnet/Mainnet automatically From c241435eac8c60e3d18695564b9d83986dbfe613 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:53:18 +0800 Subject: [PATCH 26/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 83f0c25ab62..efa8d84ae42 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -36,7 +36,7 @@ To fetch the transaction in problem, you need to provide a few things: - Sandbox node's home directory, which you were used to spin up the local sandbox node. - Accounts and contract accounts that were used during the transaction. - If it's on mainnet, the mainnet rpc URL. -- Block number or hash before the transaction to reproduce happened. This tool fetches the latest state if not given, which might not be the state you want if this transaction has mutated the blockchain state. +- Block number or hash before the transaction to reproduce what happened. This tool fetches the latest state, if not given, which might not be the state you want if this transaction has mutated the blockchain state. For example: From 4ae1b8d0997cfae1704fc744e276afe7eed7e0f9 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:53:26 +0800 Subject: [PATCH 27/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index efa8d84ae42..82f15443d1e 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -31,7 +31,7 @@ cd repro-near-funcall npm i ``` -To fetch the transaction in problem, you need to provide a few things: +To fetch the transaction in question, you need to provide a few things: - Sandbox node's home directory, which you were used to spin up the local sandbox node. - Accounts and contract accounts that were used during the transaction. From 1aef09bc8cdcedd9d0185da6553883a23bd65549 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:53:42 +0800 Subject: [PATCH 28/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 82f15443d1e..3d3a7e6d35b 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -49,7 +49,7 @@ node get-sandbox-repro-genesis.js \ -b 123456 ``` -This script will fetch account, contract, and blockchain state and generate and synthesize the genesis file replacing the current sandbox's genesis file. The old genesis file will be backed up as `genesis.json.bak`. You can now simply start the sandbox node as before, and it has accounts and contracts state loaded. Just send the transaction with `near-cli` or write a test, and you'll see the reproduced transaction executed on the sandbox node. +This script will fetch an account, contract, and blockchain state then generate and synthesize the genesis file replacing it with the current sandbox's genesis file. The old genesis file will be backed up as `genesis.json.bak`. You can now simply start the sandbox node as before and it will now have account and contract state loaded. Just send the transaction with `near-cli` or write a test and you'll see the reproduced transaction executed on the sandbox node. ### Real World Example to Reproduce a Cross Contract Call Example On Test Net From 8fe952061ce356aeb14cab7265c09f1059acf802 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:53:58 +0800 Subject: [PATCH 29/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 3d3a7e6d35b..86e32b97804 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -140,7 +140,7 @@ The information we needed can be divided into three categories, each of which is ### Genesis config -The context data when a transaction happens such as the current epoch, block height, gas price, etc., as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions) are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. +The context data when a transaction happens (current epoch, block height, gas price, etc.), as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions), are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. The first thing you'll need to do is fetch the `testnet`/`mainnet` genesis config. This can be obtained by the [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use the response file to replace the sandbox's `genesis.json`. Once complete, you will have the same configuration as `testnet`/`mainnet` in the sandbox aside from the protocol version, block height, and block timestamp. This is because genesis indicates the start of the most recent hard fork of `testnet`/`mainnet` but many blocks have been produced, protocol versions released, and time has passed the blockchain genesis. If your contract logic doesn't depend on these parameters the sandbox node should give you accurate logic, gas, and storage simulation. However, if you do require info like certain epoch and block height details you can modify `"genesis_height"` and `"protocol_version"` on your `genesis.json` file. Simply changing `"genesis_time"` won't affect. In addition, there's going to be a time travel RPC for you to tweak block timestamps. Also, note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More commonly, you most likely want to depend on how many blocks or how much time has passed. This is a relative number and you may want to base on the parameters at the time the block was produced, such as a validator set, protocol feature availability, etc. These are tied to [epoch](/docs/concepts/epoch) rather than the individual block so you don't have to strictly depend on a given block number. From a0cc53965770da43d7a289b13f67e40ea2520aee Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:54:12 +0800 Subject: [PATCH 30/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 86e32b97804..dad7f8e1a8f 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -136,7 +136,7 @@ The information we needed can be divided into three categories, each of which is 1. Genesis config 2. State records -3. Parameter provided when sending transaction +3. Parameter provided when sending the transaction ### Genesis config From f23160e0f96dc3a9c416c83f895b40f3c16c8fc5 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:54:24 +0800 Subject: [PATCH 31/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index dad7f8e1a8f..2a4e616da1b 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -141,7 +141,7 @@ The information we needed can be divided into three categories, each of which is ### Genesis config The context data when a transaction happens (current epoch, block height, gas price, etc.), as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions), are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. -The first thing you'll need to do is fetch the `testnet`/`mainnet` genesis config. This can be obtained by the [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use the response file to replace the sandbox's `genesis.json`. Once complete, you will have the same configuration as `testnet`/`mainnet` in the sandbox aside from the protocol version, block height, and block timestamp. This is because genesis indicates the start of the most recent hard fork of `testnet`/`mainnet` but many blocks have been produced, protocol versions released, and time has passed the blockchain genesis. If your contract logic doesn't depend on these parameters the sandbox node should give you accurate logic, gas, and storage simulation. However, if you do require info like certain epoch and block height details you can modify `"genesis_height"` and `"protocol_version"` on your `genesis.json` file. +The first thing you'll need to do is fetch the `testnet`/`mainnet` genesis config. This can be obtained by the [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use the response file to replace the sandbox's `genesis.json`. Once complete, you will have the same configuration as `testnet`/`mainnet` in the sandbox aside from the protocol version, block height, and block timestamp. This is because genesis indicates the start of the most recent hard fork of `testnet`/`mainnet` but many blocks have been produced, protocol versions released, and time has passed since the blockchain genesis. If your contract logic doesn't depend on these parameters the sandbox node should give you accurate logic, gas, and storage simulation. However, if you do require info like certain epoch and block height details you can modify `"genesis_height"` and `"protocol_version"` on your `genesis.json` file. Simply changing `"genesis_time"` won't affect. In addition, there's going to be a time travel RPC for you to tweak block timestamps. Also, note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More commonly, you most likely want to depend on how many blocks or how much time has passed. This is a relative number and you may want to base on the parameters at the time the block was produced, such as a validator set, protocol feature availability, etc. These are tied to [epoch](/docs/concepts/epoch) rather than the individual block so you don't have to strictly depend on a given block number. From f245a7747010f0113ceea7df75b10075e869d635 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:54:48 +0800 Subject: [PATCH 32/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 2a4e616da1b..4377db38aff 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -53,7 +53,9 @@ This script will fetch an account, contract, and blockchain state then generate ### Real World Example to Reproduce a Cross Contract Call Example On Test Net -Let's see the whole picture of reproducing a real-world transaction from testnet. Assume we have two contracts. The `simple-state` contract has a `set_status` method which stores a string for the signer of the transaction. The `cross-contract` contract has a `set_in_other_contract` which simply forwards the string to `simple-state` contract and calls it's `set_status` method. You can see this is almost the simplest case of a cross contract call situation and we'll use this example to demostrate how to reproduce it locally with the sandbox node. +Let's reproduce a `testnet` cross-contract call transaction in the simplest way possible using two contracts; `simple_state` and `cross-contract`. We'll use this example to demonstrate how to reproduce it locally with the sandbox node. + +The `simple-state` contract has a `set_status` method which stores a string for the signer of the transaction. The `cross-contract` contract has a `set_in_other_contract` method which simply forwards a string to the `simple-state` contract and calls it's `set_status` method. #### Preparation From d894d207913436aaec16000973e5a22a2d53e062 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 10:55:01 +0800 Subject: [PATCH 33/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 4377db38aff..45800d7acdc 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -145,7 +145,7 @@ The information we needed can be divided into three categories, each of which is The context data when a transaction happens (current epoch, block height, gas price, etc.), as well as `testnet`/`mainnet` specific configurations (block time / the gas amount for different kinds of actions), are all part of this category. This parameter can only be set by starting a local sandbox node from a modified version of the genesis file. The first thing you'll need to do is fetch the `testnet`/`mainnet` genesis config. This can be obtained by the [Genesis Config RPC](https://docs.near.org/docs/api/rpc#genesis-config). Use the response file to replace the sandbox's `genesis.json`. Once complete, you will have the same configuration as `testnet`/`mainnet` in the sandbox aside from the protocol version, block height, and block timestamp. This is because genesis indicates the start of the most recent hard fork of `testnet`/`mainnet` but many blocks have been produced, protocol versions released, and time has passed since the blockchain genesis. If your contract logic doesn't depend on these parameters the sandbox node should give you accurate logic, gas, and storage simulation. However, if you do require info like certain epoch and block height details you can modify `"genesis_height"` and `"protocol_version"` on your `genesis.json` file. -Simply changing `"genesis_time"` won't affect. In addition, there's going to be a time travel RPC for you to tweak block timestamps. Also, note a transaction cannot be controlled to be precisely scheduled of a given height and you should not have absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More commonly, you most likely want to depend on how many blocks or how much time has passed. This is a relative number and you may want to base on the parameters at the time the block was produced, such as a validator set, protocol feature availability, etc. These are tied to [epoch](/docs/concepts/epoch) rather than the individual block so you don't have to strictly depend on a given block number. +Simply changing `"genesis_time"` won't have an effect. In addition, there's going to be a time travel RPC for you to tweak the block timestamps. Also, note a transaction cannot be controlled to be precisely scheduled for a given height and you should not have an absolute block number in test logics. This is because it's not controllable in a real node so your contract logic shouldn't rely on that. More commonly, you would likely want to depend on how many blocks or how much time has passed. This is a relative number and you may want to base on the parameters at the time the block was produced, such as a validator set, protocol feature, availability, etc. These are tied to [epoch](/docs/concepts/epoch) rather than the individual block so you don't have to strictly depend on a given block number. ### State Records From 589265990b418f7c618bea39d39745b6a46f231b Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:19:22 +0800 Subject: [PATCH 34/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 45800d7acdc..6e387d99483 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -149,7 +149,7 @@ Simply changing `"genesis_time"` won't have an effect. In addition, there's goin ### State Records -Every state stored on the NEAR Blockchain including contract code, contract states, accounts, and access keys is in the form of state records. To run a node having an equivalent state as a `testnet`/`mainnet` node you need to apply the same state records as `testnet`/`mainnet`. You don't need to apply all states which can be many gigabytes but only those contract code/state and account keys that were used in the transaction. Once you have these state records you can apply them by either placing them in the `"records"` section of genesis _before_ starting the sandbox or use `sandbox_patch_state` RPC to add them dynamically _after_ starting the sandbox. Let's see how these state records can be obtained: +Every state stored on the NEAR Blockchain including contract code, contract states, accounts, and access keys is in the form of state records. To run a node having an equivalent state as a `testnet`/`mainnet` node you need to apply the same state records as `testnet`/`mainnet`. You don't need to apply all states, which can be many gigabytes, but only those contract code/state and account keys that were used in the transaction. Once you have these state records you can apply them by either placing them in the `"records"` section of genesis _before_ starting the sandbox or use `sandbox_patch_state` RPC to add them dynamically _after_ starting the sandbox. Let's see how these state records can be obtained: **Contract code:** From 6e581eaa45666eb3826f3c8008e9dfc998a74da7 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:19:37 +0800 Subject: [PATCH 35/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 6e387d99483..0c68f396e76 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -51,7 +51,7 @@ node get-sandbox-repro-genesis.js \ This script will fetch an account, contract, and blockchain state then generate and synthesize the genesis file replacing it with the current sandbox's genesis file. The old genesis file will be backed up as `genesis.json.bak`. You can now simply start the sandbox node as before and it will now have account and contract state loaded. Just send the transaction with `near-cli` or write a test and you'll see the reproduced transaction executed on the sandbox node. -### Real World Example to Reproduce a Cross Contract Call Example On Test Net +### Reproduce a `testnet` Cross Contract Call on a Sandbox Node Let's reproduce a `testnet` cross-contract call transaction in the simplest way possible using two contracts; `simple_state` and `cross-contract`. We'll use this example to demonstrate how to reproduce it locally with the sandbox node. From d4420332d764f08e99881df474c5e02cc85e4b99 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:19:49 +0800 Subject: [PATCH 36/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 0c68f396e76..f52c123cfc2 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -59,7 +59,9 @@ The `simple-state` contract has a `set_status` method which stores a string for #### Preparation -First let's deploy the contracts and have some transaction to reproduce on the testnet. Go to the `repro-near-funcall` repo we just cloned. Run these commands to create testnet accounts, deploy contracts and submit a transaction: +First, let's deploy the contracts and have a transaction to reproduce on `testnet`. + +Go to the `repro-near-funcall` repo we just cloned and run the following commands to create `testnet` accounts, deploy contracts, and submit a transaction: ```bash # Replace with your testnet account From ceb7b926bdc43b8bf9e42d109023fbd3fea53e84 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:20:09 +0800 Subject: [PATCH 37/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index f52c123cfc2..a7d9f1ecc6e 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -77,7 +77,7 @@ near deploy --accountId cross-contract.$REPRO_ACCOUNT --wasmFile res/cross_contr near call simple-state.$REPRO_ACCOUNT set_status --accountId $REPRO_ACCOUNT '{"message":"hello"}' ``` -Now let's try to view the status string set on testnet: +Now let's try to view the status string you set on `testnet`: ```bash near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT From 0c718a44ed46c062fda63415d71a582812defe95 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:22:27 +0800 Subject: [PATCH 38/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index a7d9f1ecc6e..e58ea91c57d 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -83,7 +83,7 @@ Now let's try to view the status string you set on `testnet`: near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT ``` -You can see the message has been set to "hello". It'll also show a link to explorer, and in the exploer page displays block hash that this view status happened, let's export it to a shell variable as well: +If all went correctly, you should see that the message has been set to "hello". It'll also show a link to NEAR Explorer which will display a block hash for this `get_status` transaction. Let's export it to a shell variable as well: ```bash # Replace with your block hash From 7ce2b651be492da0d706908bad93c0641a46f1dc Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:22:40 +0800 Subject: [PATCH 39/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index e58ea91c57d..38fad8d9bde 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -90,7 +90,7 @@ If all went correctly, you should see that the message has been set to "hello". export BLOCK=9pNq7bJ2WkYDuGT94x6Hh6jPPer5TC3Qh2dDbon5iPNz ``` -It's time to run the transaction on testnet, which we're going to reproduce shortly: +It's time to run the transaction on `testnet` which we will then reproduce locally: ```bash near call cross-contract.$REPRO_ACCOUNT set_in_other_contract --accountId $REPRO_ACCOUNT '{"message":"world"}' From a7ad7c2b656925d037488cc0dc29a038957747c2 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:23:04 +0800 Subject: [PATCH 40/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 38fad8d9bde..761bca0c2bb 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -136,7 +136,7 @@ You'll see the status has been successfully set to "world". If you're debugging Usually use the above script to fetch all information to reproduce is the most effortless way. But if you want to know every detail on how transaction execution is affected by the status of blockchain, you can follow this section to fetch the information manually. -The information we needed can be divided into three categories, each of which is configured differently: +The information needed can be divided into three categories, each of which is configured differently: 1. Genesis config 2. State records From 09962913c087de43cd1f8e302f83f569d11f6645 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:23:15 +0800 Subject: [PATCH 41/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 761bca0c2bb..70f4982f70a 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -96,7 +96,10 @@ It's time to run the transaction on `testnet` which we will then reproduce local near call cross-contract.$REPRO_ACCOUNT set_in_other_contract --accountId $REPRO_ACCOUNT '{"message":"world"}' ``` -After this transaction is done, the status of `$REPRO_ACCOUNT` should be set to "world". You can verify this by calling above `get_status` method again. +After this transaction is complete the status of `$REPRO_ACCOUNT` should be set to "world". You can verify this by calling the `get_status` method again. + +```bash +near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT``` #### Fetch Information and Reproduce Locally From 3512663df652a1d959b7b56369c99a0c732c5970 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:23:34 +0800 Subject: [PATCH 42/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 70f4982f70a..5a4f5408e3f 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -103,7 +103,7 @@ near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOU #### Fetch Information and Reproduce Locally -We can now move to reproduce this cross contract call locally. +Now let's reproduce this cross-contract call locally. 1. Spin up a sandbox node follow [this guide](https://docs.near.org/docs/develop/contracts/sandbox). Don't start the sandbox node yet. 2. Run the `get-sandbox-repro-genesis` tool to fetch information. Assume you have sandbox node's home dir in /tmp/near-sandbox. From 31ed235e7af2bd57793088639e56bd59aa27a1d4 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:23:49 +0800 Subject: [PATCH 43/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 5a4f5408e3f..96d379f58a1 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -105,7 +105,7 @@ near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOU Now let's reproduce this cross-contract call locally. -1. Spin up a sandbox node follow [this guide](https://docs.near.org/docs/develop/contracts/sandbox). Don't start the sandbox node yet. +1. Spin up a sandbox node by following [this guide](https://docs.near.org/docs/develop/contracts/sandbox). **Don't start the sandbox node yet.** 2. Run the `get-sandbox-repro-genesis` tool to fetch information. Assume you have sandbox node's home dir in /tmp/near-sandbox. ```bash From 5b73e4052e68c74d7fa05d4514007fc4f6fe8f46 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:24:15 +0800 Subject: [PATCH 44/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 96d379f58a1..e369e9f1a08 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -106,7 +106,7 @@ near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOU Now let's reproduce this cross-contract call locally. 1. Spin up a sandbox node by following [this guide](https://docs.near.org/docs/develop/contracts/sandbox). **Don't start the sandbox node yet.** -2. Run the `get-sandbox-repro-genesis` tool to fetch information. Assume you have sandbox node's home dir in /tmp/near-sandbox. +2. Run the `get-sandbox-repro-genesis` tool to fetch information. This assumes you have the sandbox node's home dir in /tmp/near-sandbox. ```bash node get-sandbox-repro-genesis.js \ From 316e798fcd4f019187e8e90dd00b3b77645c9d47 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:24:27 +0800 Subject: [PATCH 45/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index e369e9f1a08..a04c1809c2f 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -119,7 +119,7 @@ node get-sandbox-repro-genesis.js \ 3. Run sandbox node 4. Copy the `$REPRO_ACCOUNT` key from `~/.near-credentials/testnet/$REPRO_ACCOUNT.json` to `~/.near-credentials/local/`. -5. Check the status is now "hello" in sandbox: +5. Check that the status is now "hello" in sandbox: ``` export NEAR_ENV=local From 49cb0f91ba9a9226d800d706d0cf02ef627bee28 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:24:43 +0800 Subject: [PATCH 46/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index a04c1809c2f..689a6bbac2c 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -126,7 +126,7 @@ export NEAR_ENV=local near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT ``` -6. Finally we can reproduce the testnet cross transaction: +6. Finally we can reproduce the `testnet` cross-contract transaction: ``` near call cross-contract.$REPRO_ACCOUNT set_in_other_contract --accountId $REPRO_ACCOUNT '{"message":"world"}' From 82f00217e5f50dd2050695577a9a8e968c2594a5 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:25:07 +0800 Subject: [PATCH 47/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index 689a6bbac2c..c0eb0e311c1 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -133,7 +133,7 @@ near call cross-contract.$REPRO_ACCOUNT set_in_other_contract --accountId $REPRO near call simple-state.$REPRO_ACCOUNT get_status "{\"account_id\":\"$REPRO_ACCOUNT\"}" --accountId $REPRO_ACCOUNT ``` -You'll see the status has been successfully set to "world". If you're debugging a contract bug and want to avoid regression in future, it's recommended to keep the genesis generated by `get-sandbox0repro-genesis.js` as a fixture and write a test script to run the transaction on sandbox node. You can refer to [this doc](https://docs.near.org/docs/develop/contracts/sandbox) about writing sandbox test script. +You should see that the status has been successfully set to "world". If you're debugging a contract bug and want to avoid regression in the future, it's recommended to keep the genesis generated by `get-sandbox0repro-genesis.js` as a fixture and write a test script to run the transaction on a sandbox node. You can refer to [this doc](https://docs.near.org/docs/develop/contracts/sandbox) about writing sandbox test script. ## Obtain Information from Testnet/Mainnet Manually From f8a39aa7ea15cfbd79b491162a6bf7174841d3ce Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 21 Jun 2021 14:25:36 +0800 Subject: [PATCH 48/48] Update docs/develop/contracts/debug-locally.md Co-authored-by: Josh Ford --- docs/develop/contracts/debug-locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/contracts/debug-locally.md b/docs/develop/contracts/debug-locally.md index c0eb0e311c1..fcecc17d212 100644 --- a/docs/develop/contracts/debug-locally.md +++ b/docs/develop/contracts/debug-locally.md @@ -137,7 +137,7 @@ You should see that the status has been successfully set to "world". If you're d ## Obtain Information from Testnet/Mainnet Manually -Usually use the above script to fetch all information to reproduce is the most effortless way. But if you want to know every detail on how transaction execution is affected by the status of blockchain, you can follow this section to fetch the information manually. +Usually, using the above script to fetch all information to reproduce is the most effortless way. But if you want to know every detail on how a transaction execution is affected by the status of the blockchain, you can follow this section to fetch the information manually. The information needed can be divided into three categories, each of which is configured differently: