Skip to content

Commit 73970fb

Browse files
committed
Implement Patch::memory_limit
1 parent b61a1a8 commit 73970fb

3 files changed

Lines changed: 22 additions & 11 deletions

File tree

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ pub trait VM {
116116

117117
/// A sequencial VM. It uses sequencial memory representation and hash
118118
/// map storage for accounts.
119-
pub type SeqContextVM<P> = ContextVM<SeqMemory, P>;
119+
pub type SeqContextVM<P> = ContextVM<SeqMemory<P>, P>;
120120
/// A sequencial transaction VM. This is same as `SeqContextVM` except
121121
/// it runs at transaction level.
122-
pub type SeqTransactionVM<P> = TransactionVM<SeqMemory, P>;
122+
pub type SeqTransactionVM<P> = TransactionVM<SeqMemory<P>, P>;
123123

124124
/// A VM that executes using a context and block information.
125125
pub struct ContextVM<M, P: Patch> {

src/memory.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
use bigint::{U256, M256};
44

55
use super::errors::NotSupportedError;
6+
use super::Patch;
7+
use std::marker::PhantomData;
68

79
/// Represent a memory in EVM. Read should always succeed. Write can
810
/// fall.
@@ -28,28 +30,30 @@ pub trait Memory {
2830

2931
/// A sequencial memory. It uses Rust's `Vec` for internal
3032
/// representation.
31-
pub struct SeqMemory {
33+
pub struct SeqMemory<P: Patch> {
3234
memory: Vec<u8>,
35+
_marker: PhantomData<P>,
3336
}
3437

35-
impl Default for SeqMemory {
36-
fn default() -> SeqMemory {
38+
impl<P: Patch> Default for SeqMemory<P> {
39+
fn default() -> SeqMemory<P> {
3740
SeqMemory {
3841
memory: Vec::new(),
42+
_marker: PhantomData,
3943
}
4044
}
4145
}
4246

43-
impl SeqMemory {
47+
impl<P: Patch> SeqMemory<P> {
4448
pub fn len(&self) -> usize {
4549
self.memory.len()
4650
}
4751
}
4852

49-
impl Memory for SeqMemory {
53+
impl<P: Patch> Memory for SeqMemory<P> {
5054
fn check_write(&self, index: U256) -> Result<(), NotSupportedError> {
5155
let end = index + 32.into();
52-
if end > U256::from(usize::max_value()) {
56+
if end > U256::from(P::memory_limit()) {
5357
Err(NotSupportedError::MemoryIndexNotSupported)
5458
} else {
5559
Ok(())
@@ -61,7 +65,7 @@ impl Memory for SeqMemory {
6165
return Ok(());
6266
}
6367

64-
if M256::from(start) + M256::from(len) < M256::from(start) {
68+
if start.saturating_add(len) > U256::from(P::memory_limit()) {
6569
Err(NotSupportedError::MemoryIndexNotSupported)
6670
} else {
6771
self.check_write(start + len - U256::from(1u64))
@@ -70,7 +74,7 @@ impl Memory for SeqMemory {
7074

7175
fn write(&mut self, index: U256, value: M256) -> Result<(), NotSupportedError> {
7276
let end = M256::from(index) + 32.into();
73-
if end > M256::from(usize::max_value()) {
77+
if end > M256::from(P::memory_limit()) {
7478
return Err(NotSupportedError::MemoryIndexNotSupported);
7579
}
7680

@@ -81,7 +85,7 @@ impl Memory for SeqMemory {
8185
}
8286

8387
fn write_raw(&mut self, index: U256, value: u8) -> Result<(), NotSupportedError> {
84-
if index > U256::from(usize::max_value()) {
88+
if index > U256::from(P::memory_limit()) {
8589
return Err(NotSupportedError::MemoryIndexNotSupported);
8690
}
8791

src/patch/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub trait Patch {
4141
/// If true, only consume at maximum l64(after_gas) when
4242
/// CALL/CALLCODE/DELEGATECALL.
4343
fn call_create_l64_after_gas() -> bool;
44+
/// Maximum size of the memory, in bytes.
45+
fn memory_limit() -> usize;
4446
/// Precompiled contracts at given address, with required code,
4547
/// and its definition.
4648
fn precompileds() -> &'static [(Address, Option<&'static [u8]>, Box<Precompiled>)];
@@ -79,6 +81,7 @@ impl Patch for FrontierPatch {
7981
fn has_delegate_call() -> bool { false }
8082
fn err_on_call_with_more_gas() -> bool { true }
8183
fn call_create_l64_after_gas() -> bool { false }
84+
fn memory_limit() -> usize { usize::max_value() }
8285
fn precompileds() -> &'static [(Address, Option<&'static [u8]>, Box<Precompiled>)] {
8386
ETC_PRECOMPILEDS.deref() }
8487
}
@@ -99,6 +102,7 @@ impl Patch for HomesteadPatch {
99102
fn has_delegate_call() -> bool { true }
100103
fn err_on_call_with_more_gas() -> bool { true }
101104
fn call_create_l64_after_gas() -> bool { false }
105+
fn memory_limit() -> usize { usize::max_value() }
102106
fn precompileds() -> &'static [(Address, Option<&'static [u8]>, Box<Precompiled>)] {
103107
ETC_PRECOMPILEDS.deref() }
104108
}
@@ -119,6 +123,7 @@ impl Patch for VMTestPatch {
119123
fn has_delegate_call() -> bool { false }
120124
fn err_on_call_with_more_gas() -> bool { true }
121125
fn call_create_l64_after_gas() -> bool { false }
126+
fn memory_limit() -> usize { usize::max_value() }
122127
fn precompileds() -> &'static [(Address, Option<&'static [u8]>, Box<Precompiled>)] {
123128
ETC_PRECOMPILEDS.deref() }
124129
}
@@ -139,6 +144,7 @@ impl Patch for EIP150Patch {
139144
fn has_delegate_call() -> bool { true }
140145
fn err_on_call_with_more_gas() -> bool { false }
141146
fn call_create_l64_after_gas() -> bool { true }
147+
fn memory_limit() -> usize { usize::max_value() }
142148
fn precompileds() -> &'static [(Address, Option<&'static [u8]>, Box<Precompiled>)] {
143149
ETC_PRECOMPILEDS.deref() }
144150
}
@@ -159,6 +165,7 @@ impl Patch for EIP160Patch {
159165
fn has_delegate_call() -> bool { true }
160166
fn err_on_call_with_more_gas() -> bool { false }
161167
fn call_create_l64_after_gas() -> bool { true }
168+
fn memory_limit() -> usize { usize::max_value() }
162169
fn precompileds() -> &'static [(Address, Option<&'static [u8]>, Box<Precompiled>)] {
163170
ETC_PRECOMPILEDS.deref() }
164171
}

0 commit comments

Comments
 (0)