From 2d63f5f95b59cbcc9bcb7774fd48e4d9050d4d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81rgio?= Date: Fri, 19 Jul 2024 19:58:20 +0100 Subject: [PATCH 1/5] Relayer nonce collisions --- .../1.chain-abstraction/meta-transactions.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/2.build/1.chain-abstraction/meta-transactions.md b/docs/2.build/1.chain-abstraction/meta-transactions.md index 7167cca077a..6adb382c4ca 100644 --- a/docs/2.build/1.chain-abstraction/meta-transactions.md +++ b/docs/2.build/1.chain-abstraction/meta-transactions.md @@ -106,6 +106,21 @@ Progress is being made to make this possible in the future. +### High volume parallel processing + +When running a relayer that handles a large number of transactions, issues will quickly arise due to each transaction requiring a unique nonce. If multiple transactions are sent from the same access key simultaneously, the process becomes error-prone. + +Fortunately, this is easy to resolve. Adding multiple full access keys to the NEAR account used for relaying (up to 20 keys can make a significant difference) will help. Then, relaying transactions using instances of the Account object created from the various keypairs associated with the account. + +To add a key, generate a new keypair and use the original account object to call the addKey method + +```typescript +const keyPair = nearAPI.KeyPair.fromRandom("ed25519"); + +const receipt = await account.addKey(keyPair.getPublicKey().toString()) +``` + +After saving these keys, its possible to rotate the private keys randomly when instantiating accounts before relaying ensuring you won't create a nonce collision. ### Gating the relayer From e942c321f0c1b9337387084192c9c7a3fd356b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Seco?= <52105707+SurgeCode@users.noreply.github.com> Date: Mon, 22 Jul 2024 11:17:08 +0100 Subject: [PATCH 2/5] Update docs/2.build/1.chain-abstraction/meta-transactions.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Damián Parrino --- docs/2.build/1.chain-abstraction/meta-transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.build/1.chain-abstraction/meta-transactions.md b/docs/2.build/1.chain-abstraction/meta-transactions.md index 6adb382c4ca..7deb6370ae4 100644 --- a/docs/2.build/1.chain-abstraction/meta-transactions.md +++ b/docs/2.build/1.chain-abstraction/meta-transactions.md @@ -112,7 +112,7 @@ When running a relayer that handles a large number of transactions, issues will Fortunately, this is easy to resolve. Adding multiple full access keys to the NEAR account used for relaying (up to 20 keys can make a significant difference) will help. Then, relaying transactions using instances of the Account object created from the various keypairs associated with the account. -To add a key, generate a new keypair and use the original account object to call the addKey method +To add a key, generate a new key pair and use the original account object to call the `addKey` method: ```typescript const keyPair = nearAPI.KeyPair.fromRandom("ed25519"); From 3193a66f8384357dadd4934cd5988df49333a086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Seco?= <52105707+SurgeCode@users.noreply.github.com> Date: Mon, 22 Jul 2024 11:17:22 +0100 Subject: [PATCH 3/5] Update docs/2.build/1.chain-abstraction/meta-transactions.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Damián Parrino --- docs/2.build/1.chain-abstraction/meta-transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.build/1.chain-abstraction/meta-transactions.md b/docs/2.build/1.chain-abstraction/meta-transactions.md index 7deb6370ae4..e9e879e2756 100644 --- a/docs/2.build/1.chain-abstraction/meta-transactions.md +++ b/docs/2.build/1.chain-abstraction/meta-transactions.md @@ -114,7 +114,7 @@ Fortunately, this is easy to resolve. Adding multiple full access keys to the NE To add a key, generate a new key pair and use the original account object to call the `addKey` method: -```typescript +```js const keyPair = nearAPI.KeyPair.fromRandom("ed25519"); const receipt = await account.addKey(keyPair.getPublicKey().toString()) From 98b5e1651c5263ae8e0c3093ad5ec043fa1f6c30 Mon Sep 17 00:00:00 2001 From: Guille Date: Mon, 2 Sep 2024 12:52:54 +0200 Subject: [PATCH 4/5] Update meta-transactions.md --- docs/2.build/1.chain-abstraction/meta-transactions.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/2.build/1.chain-abstraction/meta-transactions.md b/docs/2.build/1.chain-abstraction/meta-transactions.md index e9e879e2756..1b3bdbfcc43 100644 --- a/docs/2.build/1.chain-abstraction/meta-transactions.md +++ b/docs/2.build/1.chain-abstraction/meta-transactions.md @@ -108,11 +108,14 @@ Progress is being made to make this possible in the future. ### High volume parallel processing -When running a relayer that handles a large number of transactions, issues will quickly arise due to each transaction requiring a unique nonce. If multiple transactions are sent from the same access key simultaneously, the process becomes error-prone. +When running a relayer that handles a large number of transactions, you will quickly run into a `nonce` collision problem. At the protocol level, transactions have a unique number that identifies them (nonce) that helps to mitigate reply attacks. Each key on an account has its own nonce, and the nonce is expected to increase with each signature the key creates. -Fortunately, this is easy to resolve. Adding multiple full access keys to the NEAR account used for relaying (up to 20 keys can make a significant difference) will help. Then, relaying transactions using instances of the Account object created from the various keypairs associated with the account. +When multiple transactions are sent from the same access key simultaneously, their nonces might collide. Imagine the relayer creates 3 transactions `Tx1`, `Tx2`, `Tx3` and send them in very short distance from each other, and lets assume that Tx3 has the largest nonce. If Tx3 ends up being processed before Tx1 (because of network delay, or simply because a node picks Tx3 before Tx1), then Tx3 will execute, but Tx1 and Tx2 will fail, because they have smaller nonce! -To add a key, generate a new key pair and use the original account object to call the `addKey` method: +One way to mitigate this is to sign each transaction with a different key. Adding multiple full access keys to the NEAR account used for relaying (up to 20 keys can make a significant difference) will help. + +
+ Adding keys ```js const keyPair = nearAPI.KeyPair.fromRandom("ed25519"); @@ -122,6 +125,8 @@ const receipt = await account.addKey(keyPair.getPublicKey().toString()) After saving these keys, its possible to rotate the private keys randomly when instantiating accounts before relaying ensuring you won't create a nonce collision. +
+ ### Gating the relayer In most production applications it's expected that you want to be able to gate the relayer to only be used in certain cases. From 0943fb874580f973192aa39ab865263191e9ec1f Mon Sep 17 00:00:00 2001 From: Guille Date: Mon, 2 Sep 2024 12:54:02 +0200 Subject: [PATCH 5/5] Update docs/2.build/1.chain-abstraction/meta-transactions.md --- docs/2.build/1.chain-abstraction/meta-transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.build/1.chain-abstraction/meta-transactions.md b/docs/2.build/1.chain-abstraction/meta-transactions.md index 1b3bdbfcc43..7e55132236a 100644 --- a/docs/2.build/1.chain-abstraction/meta-transactions.md +++ b/docs/2.build/1.chain-abstraction/meta-transactions.md @@ -110,7 +110,7 @@ Progress is being made to make this possible in the future. When running a relayer that handles a large number of transactions, you will quickly run into a `nonce` collision problem. At the protocol level, transactions have a unique number that identifies them (nonce) that helps to mitigate reply attacks. Each key on an account has its own nonce, and the nonce is expected to increase with each signature the key creates. -When multiple transactions are sent from the same access key simultaneously, their nonces might collide. Imagine the relayer creates 3 transactions `Tx1`, `Tx2`, `Tx3` and send them in very short distance from each other, and lets assume that Tx3 has the largest nonce. If Tx3 ends up being processed before Tx1 (because of network delay, or simply because a node picks Tx3 before Tx1), then Tx3 will execute, but Tx1 and Tx2 will fail, because they have smaller nonce! +When multiple transactions are sent from the same access key simultaneously, their nonces might collide. Imagine the relayer creates 3 transactions `Tx1`, `Tx2`, `Tx3` and send them in very short distance from each other, and lets assume that `Tx3` has the largest nonce. If `Tx3` ends up being processed before `Tx1` (because of network delays, or a node picks `Tx3` first), then `Tx3` will execute, but `Tx1` and `Tx2` will fail, because they have smaller nonce! One way to mitigate this is to sign each transaction with a different key. Adding multiple full access keys to the NEAR account used for relaying (up to 20 keys can make a significant difference) will help.