Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dust account replay security #169

Closed
gavofyork opened this issue Nov 1, 2016 · 5 comments
Closed

Dust account replay security #169

gavofyork opened this issue Nov 1, 2016 · 5 comments
Labels

Comments

@gavofyork
Copy link

gavofyork commented Nov 1, 2016

Brief

EIP #168 allows for unused accounts to be reclaimed, freeing space in the state trie. However, these reclaimed accounts are now vulnerable to replay attacks. This is a proposal to ensure such accounts remain secure for reuse, against replay attacks, even after being reaped.

Description

Rather than having the account nonce begin at zero and increment, which is open to replay attacks if the nonce is reset during the lifetime of the account, instead it begins equal to the block number in which it is created.

We only increment the nonce at most once per block. This ensures that the range of nonce between resets is never repeated and thus avoids replay attacks, particularly on accounts which send more transactions than their lifetime measured in blocks.

Specification

Variant A

a. Newly created account entries get a nonce equal to the current block number.
b. Transactions do not result in the increment of the sender account by one.
c. At the end of the block, each account that sent at least one transaction has its nonce incremented by one.
d. A transaction of the same hash may not be included in the same block.

Variant B:

Exactly as Variant A with additional rules:

e. Transactions include an additional pre-signature field, ordering.
f. A transaction of ordering = O is only valid for inclusion in a block if either:

  • O = 0; or
  • there exists, in this block, at least one transaction of ordering = O - 1.

Variant C

a. Newly created account entries get a nonce equal to the current block number times MAX_TXS_PER_ACCT_PER_BLOCK.
b. Transactions can only be sent from a nonempty account.
c. If an account has nonzero nonce, then a transaction sent from it may be included in the current block iff:

  • the transaction has the same nonce as the account nonce; and
  • the nonce divided by MAX_TXS_PER_ACCT_PER_BLOCK is no greater than the current block number.
    The account nonce is incremented as normal if the transaction is included.

Example MAX_TXS_PER_ACCT_PER_BLOCK could be 64.

Critique

In general this mechanism leads to a fairly modest state trie increase of at most 3 bytes per account (which may be reducible through contextual compression) and around 4 bytes per transaction.

This mechanism, in the worst case, delivers a little more faff for transactors who make many transactions in a batch since any that are not included in the same block will necessarily need re-signing and re-submitting. This is mitigated by the fact that large batches are automated and relatively uncommon. Furthermore, large batch payments are better managed through a simple suiciding contract-creation transaction which guarantees they are all processed and largely moots the problem that they could be split with many transactions needing to be re-submitted.

Variant 2 exists to allow multiple transactions, possibly of equivalent content, to be included in the same block with a particular ordering. It would cost around an extra byte per transaction. If variant 2 were not adopted, similar functionality could alternatively be provided through a suiciding contract-creation transaction executing a batch.

@vbuterin
Copy link
Contributor

vbuterin commented Nov 4, 2016

I think there may be a simpler way to do this:

  • If an account is empty, and it is touched, its nonce is set to block.number * MAX_TXS_PER_ACCT_PER_BLOCK.
  • Transactions can only be sent from a nonempty account.
  • If an account has nonzero nonce, then the transaction must have the same nonce as the account nonce. The account nonce is incremented.
  • If an account has nonce == (block.number + 1) * MAX_TXS_PER_ACCT_PER_BLOCK, then transactions from that account are invalid until the block number is incremented.

We could set MAX_TXS_PER_ACCT_PER_BLOCK to something like 64.

@janx
Copy link
Member

janx commented Dec 2, 2016

There may be another two ways:

Way 1:

  • record in local db a global MAX_NONCE which is the largest of all account nonces
  • newly created account get a nonce equal to MAX_NONCE

Way 2:

  • after block X, use RLP type (int, int) for new nonce, which is a pair of integers:
    • nonce[0] represents account generation
    • nonce[1] represents txs number sent from account as usual
  • if an account is reaped, only nonce[1] is reset to zero, nonce[0] is left unmodified
  • if an account is touched, it's nonce[0] is incremented

The first way add nothing new to account/transaction, while the second adds ~2 bytes to account data.

@gumb0
Copy link
Member

gumb0 commented Feb 2, 2018

Way 1:

  • record in local db a global MAX_NONCE which is the largest of all account nonces
  • newly created account get a nonce equal to MAX_NONCE

Possible downside of this I see: fast sync after downloading the state trie would need to go over all accounts to find the current MAX_NONCE

@github-actions
Copy link

github-actions bot commented Jan 4, 2022

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the stale label Jan 4, 2022
@github-actions
Copy link

This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants
@janx @Arachnid @gavofyork @gumb0 @vbuterin @Souptacular and others