You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Traditionally transactions are protected from replaying based on UTXO and nonce. Nonce is used to uniquely identify the transaction and to prevent replaying.
When dealing with state based accounts instead of UTXO, you can't be sure the given input is available. E.g., if in one fork of the chain you receive 1M tokens and decide to spend 1K of them, the same transaction can be valid in another fork. But, let's say, in that fork you didn't receive 1M tokens, and you just spent 1K of your last tokens and your account was nuked.
To prevent this from happening we introduce an additional fields in the transaction. The hash of the block on which this transaction is based (let's call it block_hash). So if you base your transaction in the given fork, then this transaction can't be replayed in any other fork that doesn't contain given block hash.
This change protects from forks, but doesn't protect from delaying a transaction for infinite amount of time and later replaying it (assuming the nonce didn't change). To resolve this we introduce an additional field that indicates transaction expiration. It's the number of blocks from the block_hash during which the transaction is considered valid. E.g. if the transaction is based on the block hash ABC and the validity period is set to 3 blocks. Then only the next 3 blocks after block ABC can include the given transaction.
We should also consider limitations of the given approach. If we allow a validity period to be very large, then we'll need to maintain a large history of previous block hashes to verify if the given transaction is still valid. Instead we should limit the validity period to a small number, e.g. 60 blocks which would indicate that the given transaction has to be taken into a block in about 1 minute.
Fields to add:
/// The hash of the block in the blockchain on top of which the given transaction is valid.
pub block_hash: CryptoHash;
/// The number of blocks from the given block hash the given transaction is valid
pub validity_period: BlockIndex;
Constant to introduce in the genesis config:
pub MAX_TRANSACTION_VALIDITY_PERIOD: BlockIndex; // default can be 60
For all of this to work, the Runtime should receive the block hash history up to the MAX_TRANSACTION_VALIDITY_PERIOD blocks.
The text was updated successfully, but these errors were encountered:
Traditionally transactions are protected from replaying based on UTXO and nonce. Nonce is used to uniquely identify the transaction and to prevent replaying.
When dealing with state based accounts instead of UTXO, you can't be sure the given input is available. E.g., if in one fork of the chain you receive 1M tokens and decide to spend 1K of them, the same transaction can be valid in another fork. But, let's say, in that fork you didn't receive 1M tokens, and you just spent 1K of your last tokens and your account was nuked.
To prevent this from happening we introduce an additional fields in the transaction. The hash of the block on which this transaction is based (let's call it
block_hash
). So if you base your transaction in the given fork, then this transaction can't be replayed in any other fork that doesn't contain given block hash.This change protects from forks, but doesn't protect from delaying a transaction for infinite amount of time and later replaying it (assuming the nonce didn't change). To resolve this we introduce an additional field that indicates transaction expiration. It's the number of blocks from the
block_hash
during which the transaction is considered valid. E.g. if the transaction is based on the block hashABC
and the validity period is set to 3 blocks. Then only the next 3 blocks after blockABC
can include the given transaction.We should also consider limitations of the given approach. If we allow a validity period to be very large, then we'll need to maintain a large history of previous block hashes to verify if the given transaction is still valid. Instead we should limit the validity period to a small number, e.g. 60 blocks which would indicate that the given transaction has to be taken into a block in about 1 minute.
Fields to add:
Constant to introduce in the genesis config:
For all of this to work, the
Runtime
should receive the block hash history up to theMAX_TRANSACTION_VALIDITY_PERIOD
blocks.The text was updated successfully, but these errors were encountered: