Skip to content

Commit a44cdd7

Browse files
authored
[Anvil] Fix impersonation marker collision with storage keys (#489)
* [Anvil] Fix impersonation marker collision with storage keys Use 0xDE marker instead of 0x00 for impersonated transaction signatures to avoid collision with Solidity mapping key computations for slot 0. Closes #488 * !fixup af24a53a0 * Use original syntax * fix
1 parent f42b8e5 commit a44cdd7

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

crates/anvil-polkadot/src/api_server/revive_conversions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ impl From<RevivePrestateTraceInfo> for AccountState {
420420
.map(|(k, v)| {
421421
(
422422
B256::from_slice(k.0.as_slice()),
423-
B256::from_slice(v.unwrap_or_default().0.as_slice()),
423+
B256::from_slice(v.unwrap_or(Bytes(vec![0u8; 32])).0.as_slice()),
424424
)
425425
})
426426
.collect(),

crates/anvil-polkadot/src/api_server/server.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,8 +849,14 @@ impl ApiServer {
849849
.sign_transaction(Address::from(ReviveAddress::new(addr)), tx)?
850850
.signed_payload(),
851851
None => {
852-
let mut fake_signature = [0; 65];
852+
// Create impersonated signature format:
853+
// [0; 12] + [address; 20] + [IMPERSONATION_MARKER; 32] + [recovery_id; 1]
854+
// The recovery_id (byte 64) must be 0 or 1 for valid ECDSA signatures
855+
use crate::substrate_node::host::IMPERSONATION_MARKER;
856+
let mut fake_signature = [IMPERSONATION_MARKER; 65];
857+
fake_signature[..12].fill(0);
853858
fake_signature[12..32].copy_from_slice(from.as_bytes());
859+
fake_signature[64] = 0; // Valid recovery ID
854860
tx.with_signature(fake_signature).signed_payload()
855861
}
856862
};

crates/anvil-polkadot/src/substrate_node/host.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//! This module implements tweaked versions of the host functions from `sp-io`, which
1313
//! can recognize fake signatures used for impersonated transactions, and can recover
1414
//! the signer address from them, while expecting those fake signatures to be built in
15-
//! a certain way ([0; 12] + sender's Ethereum address + [0; 33]).
15+
//! a certain way ([0; 12] + sender's Ethereum address + [IMPERSONATION_MARKER; 32] + recovery_id).
1616
//!
1717
//! The tweaked host functions are especially useful in the context of overriding the
1818
//! same `sp-io` host functions in the wasm executor type.
@@ -26,10 +26,19 @@ use sp_runtime_interface::{
2626
runtime_interface,
2727
};
2828

29+
/// Magic marker used to identify impersonated transactions.
30+
/// Using 0xDE for "DEfake" - a distinctive pattern that won't collide with legitimate EVM data.
31+
/// Previously we used [0; 33] but this collided with Solidity mapping key computations
32+
/// for slot 0 (which also have 32 trailing zero bytes).
33+
pub const IMPERSONATION_MARKER: u8 = 0xDE;
34+
2935
// The host functions in this module expect transactions
3036
// with fake signatures conforming the format checked in this function.
37+
// Format: [0; 12] + [20-byte address] + [IMPERSONATION_MARKER; 32] + [recovery_id]
38+
// Note: We only check bytes 32..64 (the 's' component of ECDSA signature) for the marker.
39+
// Byte 64 (recovery_id/v) must be a valid value (0 or 1) for the transaction to be accepted.
3140
pub fn is_impersonated(sig: &[u8]) -> bool {
32-
sig[..12] == [0; 12] && sig[32..64] == [0; 32]
41+
sig[..12] == [0; 12] && sig[32..64] == [IMPERSONATION_MARKER; 32]
3342
}
3443

3544
/// Recover sender address from signed transaction, handling impersonated transactions.
@@ -63,7 +72,8 @@ pub trait Crypto {
6372
"impersonation for: {:?}",
6473
&sig[12..32]
6574
);
66-
let mut res = [0u8; 64];
75+
let mut res = [IMPERSONATION_MARKER; 64];
76+
res[..12].fill(0);
6777
res[12..32].copy_from_slice(&sig[12..32]);
6878
Ok(res)
6979
} else {
@@ -83,7 +93,9 @@ pub trait Crypto {
8393
"impersonation for: {:?}",
8494
&sig[12..32]
8595
);
86-
let mut res = [0u8; 64];
96+
97+
let mut res = [IMPERSONATION_MARKER; 64];
98+
res[..12].fill(0);
8799
res[12..32].copy_from_slice(&sig[12..32]);
88100
Ok(res)
89101
} else {

0 commit comments

Comments
 (0)