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

Feat: mega EOF #63

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b94b08e
EOF config
mrLSD Oct 11, 2024
f9d0094
Merge branch 'feat/eip-7702' into feat/mega-eof
mrLSD Oct 15, 2024
5a545b4
Executor for EOF basics
mrLSD Oct 16, 2024
8e8b3b2
Fixed clippy for tracign feature. Changed EOF create
mrLSD Oct 16, 2024
7b21250
Merge branch 'feat/prague-hard-fork' into feat/mega-eof
mrLSD Oct 17, 2024
9ed63c1
EOF basic header decode, and errors management
mrLSD Oct 18, 2024
348f583
EOF header decoder tests
mrLSD Oct 19, 2024
36235d1
EOF decode: Header, Body, surplus. EOF tests coverage
mrLSD Oct 24, 2024
3625a0f
EOF flow adjustment
mrLSD Oct 30, 2024
8743738
Extend Opcode definitions and call
mrLSD Oct 31, 2024
c6078f9
EIP-7480 and tests
mrLSD Nov 5, 2024
9dc9f35
Extend EIP-7480 and tests
mrLSD Nov 6, 2024
94d1184
EIP-663 and tests
mrLSD Nov 9, 2024
ddaf13b
Optimize bitwise byte ops (#68)
mrLSD Nov 11, 2024
03ebc1d
Basic EIP-7069 and gas costs
mrLSD Nov 12, 2024
8fad857
Feat: update toolchain and refactore dependencies (#69)
mrLSD Nov 13, 2024
481e233
Merge branch 'master' into feat/mega-eof
mrLSD Nov 13, 2024
c0fd2d7
EIP-7069: ext_call
mrLSD Nov 14, 2024
56c3e39
EIP-7069 ext_call and gas cost calc
mrLSD Nov 15, 2024
8fdb235
chore: add catalog entities (#70)
diegofigs Nov 15, 2024
faea170
EIP-7069 - EXT-related functions
mrLSD Nov 15, 2024
f7bdd0d
eof-create basics
mrLSD Nov 16, 2024
c38ef20
eof-create refactore
mrLSD Nov 16, 2024
9c7c039
Added RJUMP* functions
mrLSD Nov 18, 2024
8557dfd
EIP-4200 static jumps
mrLSD Nov 19, 2024
d7f1580
ci: add security workflow (#71)
diegofigs Nov 29, 2024
44a2e92
EIP-4750: CALLF and EOF call code refactoring
mrLSD Dec 12, 2024
4212667
Feat: EIP-7702 implementation (#56)
mrLSD Dec 13, 2024
ec7f7f6
Merge branch 'feat/mega-eof' into feat/prague-hard-fork
mrLSD Dec 13, 2024
1016602
Resolve merge conflicts
mrLSD Dec 13, 2024
a9ed0cd
Update version
mrLSD Dec 13, 2024
bd982ea
EIP-4750: RETF
mrLSD Dec 13, 2024
20b2bc3
EIP-6206: JUMPF
mrLSD Dec 13, 2024
3dc8992
Merge branch 'master' of github.com:aurora-is-near/sputnikvm into fea…
mrLSD Dec 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .catalog-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
apiVersion: backstage.io/v1alpha1
kind: Location
metadata:
name: sputnikvm-public
description: SputnikVM repository
spec:
targets:
- ./core/.catalog-info.yaml
- ./runtime/.catalog-info.yaml
- ./gasometer/.catalog-info.yaml
---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: sputnikvm-evm
title: SputnikVM evm
description: Main library that re-exports most things
tags:
- ethereum
links: []
annotations:
aurora.dev/security-tier: "1"
spec:
owner: engine-team
type: library
lifecycle: production
3 changes: 2 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ jobs:

- name: Clippy
run: cargo clippy --workspace --all-targets -- -D clippy::all -D clippy::nursery

- name: Clippy no_std
run: cargo clippy --no-default-features -- -D clippy::all -D clippy::nursery
- name: Clippy with features
run: cargo clippy --features tracing,create-fixed -- -D clippy::all -D clippy::nursery

build:
runs-on: ubuntu-latest
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/security-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: "Security Analysis"

on:
push:
branches:
- master
pull_request:
workflow_dispatch:

jobs:
contract_analysis:
name: "Shared"
uses: aurora-is-near/.github/.github/workflows/security_analysis.yml@master
secrets: inherit
18 changes: 7 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@ keywords.workspace = true
edition.workspace = true

[workspace.dependencies]
evm = { version = "0.46.0", path = "." }
evm-core = { version = "0.46.0", path = "core", default-features = false }
evm-gasometer = { version = "0.46.0", path = "gasometer", default-features = false }
evm-runtime = { version = "0.46.0", path = "runtime", default-features = false }
primitive-types = { version = "0.12", default-features = false }
evm = { version = "0.47.0", path = "." }
evm-core = { version = "0.47.0", path = "core", default-features = false }
evm-gasometer = { version = "0.47.0", path = "gasometer", default-features = false }
evm-runtime = { version = "0.47.0", path = "runtime", default-features = false }
primitive-types = { version = "0.13", default-features = false }
auto_impl = "1.0"
sha3 = { version = "0.10", default-features = false }

[dependencies]
ethereum = { version = "0.15", default-features = false }
log = { version = "0.4", default-features = false }
primitive-types = { workspace = true, features = ["rlp"] }
rlp = { version = "0.5", default-features = false }
rlp = { version = "0.6", default-features = false, features = ["derive"] }
smallvec = "1.13"

# Optional dependencies
Expand All @@ -47,7 +46,6 @@ harness = false
[features]
default = ["std", "force-debug"]
std = [
"ethereum/std",
"log/std",
"primitive-types/std",
"rlp/std",
Expand All @@ -65,14 +63,12 @@ with-codec = [
"scale-info",
"primitive-types/codec",
"primitive-types/scale-info",
"ethereum/with-codec",
"evm-core/with-codec",
]
with-serde = [
"serde",
"primitive-types/impl-serde",
"evm-core/with-serde",
"ethereum/with-serde",
]
tracing = [
"environmental",
Expand All @@ -88,7 +84,7 @@ create-fixed = []
print-debug = ["evm-gasometer/print-debug"]

[workspace.package]
version = "0.46.0"
version = "0.47.0"
license = "Apache-2.0"
authors = ["Aurora Labs <[email protected]>", "Wei Tang <[email protected]>", "Parity Technologies <[email protected]>"]
description = "Portable Ethereum Virtual Machine implementation written in pure Rust."
Expand Down
16 changes: 16 additions & 0 deletions core/.catalog-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: sputnikvm-core
title: SputnikVM core
description: Core library defining the basic execution rules
tags:
- ethereum
links: []
annotations:
aurora.dev/security-tier: "1"
spec:
owner: engine-team
type: library
lifecycle: production
subcomponentOf: sputnikvm-evm
73 changes: 73 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,17 @@ pub enum ExitError {
UsizeOverflow,
#[cfg_attr(feature = "with-codec", codec(index = 16))]
CreateContractStartingWithEF,

#[cfg_attr(feature = "with-codec", codec(index = 17))]
EOFDecodeError(EofDecodeError),
#[cfg_attr(feature = "with-codec", codec(index = 18))]
EOFOpcodeDisabledInLegacy,
#[cfg_attr(feature = "with-codec", codec(index = 19))]
InvalidEXTCALLTarget,
#[cfg_attr(feature = "with-codec", codec(index = 20))]
EOFUnexpectedCall,
#[cfg_attr(feature = "with-codec", codec(index = 21))]
EOFFunctionStackOverflow,
}

impl From<ExitError> for ExitReason {
Expand Down Expand Up @@ -202,3 +213,65 @@ impl From<ExitFatal> for ExitReason {
Self::Fatal(s)
}
}

/// EOF decode errors.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(
feature = "with-codec",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
pub enum EofDecodeError {
/// Missing input while processing EOF.
MissingInput,
/// Missing body while processing EOF.
MissingBodyData,
/// Body size is more than specified in the header.
BodySizeMoreThanInHeader,
/// Invalid types section data.
InvalidTypesSectionData,
/// Invalid types section size.
InvalidTypesSectionSize,
/// Invalid EOF magic number.
InvalidEOFMagicNumber,
/// Invalid EOF version.
InvalidEOFVersion,
/// Invalid number for types kind
InvalidNumberForTypesKind,
/// Invalid number for code kind
InvalidNumberForCodeKind,
/// Invalid terminal byte
InvalidTerminalByte,
/// Invalid data kind
InvalidDataKind,
/// Invalid kind after code
InvalidKindAfterCode,
/// Mismatch of code and types sizes.
MismatchCodeAndTypesSize,
/// There should be at least one size.
SizesNotFound,
/// Missing size.
ShortInputForSizes,
/// Code size can't be zero
ZeroCodeSize,
/// Invalid code number.
TooManyCodeSections,
/// Invalid number of code sections.
InvalidNumberCodeSections,
/// Invalid container number.
InvalidNumberContainerSections,
/// Invalid initcode size.
InvalidEOFInitcodeSize,
/// Short body while processing EOF.
MissingBodyWithoutData,
/// Body size is more than specified in the header.
DanglingData,
/// Invalid types section data.
InvalidTypesSection,
}

impl From<EofDecodeError> for ExitError {
fn from(e: EofDecodeError) -> Self {
Self::EOFDecodeError(e)
}
}
11 changes: 4 additions & 7 deletions core/src/eval/bitwise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,14 @@ pub fn not(op1: U256) -> U256 {
#[inline]
pub fn byte(op1: U256, op2: U256) -> U256 {
let mut ret = U256::zero();

for i in 0..256 {
if i < 8 && op1 < 32.into() {
let o: usize = op1.as_usize();
if op1 < 32.into() {
let o = op1.as_usize();
for i in 0..8 {
let t = 255 - (7 - i + 8 * o);
let bit_mask = U256::one() << t;
let value = (op2 & bit_mask) >> t;
let value = (op2 >> t) & U256::one();
ret = ret.overflowing_add(value << i).0;
}
}

ret
}

Expand Down
6 changes: 1 addition & 5 deletions core/src/eval/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ macro_rules! pop_h256 {
( $machine:expr, $( $x:ident ),* ) => (
$(
let $x = match $machine.stack.pop() {
Ok(value) => {
let mut res = H256([0; 32]);
value.to_big_endian(&mut res[..]);
res
},
Ok(value) => H256(value.to_big_endian()),
Err(e) => return Control::Exit(e.into()),
};
)*
Expand Down
62 changes: 61 additions & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ mod stack;
pub mod utils;
mod valids;

pub use crate::error::{Capture, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed, Trap};
pub use crate::error::{
Capture, EofDecodeError, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed, Trap,
};
pub use crate::external::ExternalOperation;
pub use crate::memory::Memory;
pub use crate::opcode::Opcode;
Expand Down Expand Up @@ -103,6 +105,64 @@ impl Machine {
&self.position
}

/// Get the code with offset and increment the program counter.
/// If code range is out of bound, return empty slice.
///
/// ## Errors
/// Returns `ExitReason` if the program counter is invalid.
pub fn get_code_and_inc_pc(&mut self, offset: usize) -> Result<&[u8], ExitReason> {
let position = match &self.position {
Ok(pos) => *pos,
Err(e) => return Err(e.clone()),
};
let data = self
.code
.get(position..position + offset)
.unwrap_or_default();
self.position = Ok(position + offset);
Ok(data)
}

/// Increment the program counter with offset.
///
/// ## Errors
/// Returns `ExitReason` if the program counter is invalid.
pub fn inc_pc(&mut self, offset: usize) -> Result<(), ExitReason> {
let position = match &self.position {
Ok(pos) => *pos,
Err(e) => return Err(e.clone()),
};
self.position = Ok(position + offset);
Ok(())
}

/// Get the code with offset.
/// If code range is out of bound, return empty slice.
///
/// ## Errors
/// Returns `ExitReason` if the program counter is invalid.
pub fn get_code_with_offset(&mut self, offset: usize) -> Result<&[u8], ExitReason> {
let position = match &self.position {
Ok(pos) => *pos,
Err(e) => return Err(e.clone()),
};

Ok(self
.code
.get(position..position + offset)
.unwrap_or_default())
}

/// Set the program code. Usefuk for EOF.
pub fn set_code(&mut self, code: &[u8]) {
self.code = Rc::new(code.to_vec());
}

/// Set program counter. Useful for EOF.
pub fn set_pc(&mut self, position: usize) {
self.position = Ok(position);
}

/// Create a new machine with given code and data.
#[must_use]
pub fn new(
Expand Down
2 changes: 1 addition & 1 deletion core/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl Memory {

if target_size > value.len() {
self.data[offset..((value.len()) + offset)].clone_from_slice(value);
for index in (value.len())..target_size {
for index in value.len()..target_size {
self.data[offset + index] = 0;
}
} else {
Expand Down
15 changes: 15 additions & 0 deletions core/src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,21 @@ impl Display for Opcode {
Self::LOG2 => "LOG2",
Self::LOG3 => "LOG3",
Self::LOG4 => "LOG4",
Self::DATALOAD => "DATALOAD",
Self::DATALOADN => "DATALOADN",
Self::DATASIZE => "DATASIZE",
Self::DATACOPY => "DATACOPY",
Self::RJUMP => "RJUMP",
Self::RJUMPI => "RJUMPI",
Self::RJUMPV => "RJUMPV",
Self::CALLF => "CALLF",
Self::RETF => "RETF",
Self::JUMPF => "JUMPF",
Self::DUPN => "DUPN",
Self::SWAPN => "SWAPN",
Self::EXCHANGE => "EXCHANGE",
Self::EOFCREATE => "EOFCREATE",
Self::RETURNCONTRACT => "RETURNCONTRACT",
Self::CREATE => "CREATE",
Self::CREATE2 => "CREATE2",
Self::CALL => "CALL",
Expand Down
12 changes: 2 additions & 10 deletions core/src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,7 @@ impl Stack {
/// Return `ExitError`
#[inline]
pub fn pop_h256(&mut self) -> Result<H256, ExitError> {
self.pop().map(|it| {
let mut res = H256([0; 32]);
it.to_big_endian(&mut res.0);
res
})
self.pop().map(|it| H256(it.to_big_endian()))
}

/// Push a new value into the stack. If it will exceed the stack limit,
Expand Down Expand Up @@ -106,11 +102,7 @@ impl Stack {
/// # Errors
/// Return `ExitError`
pub fn peek_h256(&self, no_from_top: usize) -> Result<H256, ExitError> {
self.peek(no_from_top).map(|it| {
let mut res = H256([0; 32]);
it.to_big_endian(&mut res.0);
res
})
self.peek(no_from_top).map(|it| H256(it.to_big_endian()))
}

/// Peek a value at given index for the stack as usize.
Expand Down
2 changes: 2 additions & 0 deletions evm-tests/EIP-152/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Open Ethereum. If not, see <http://www.gnu.org/licenses/>.

#![allow(clippy::too_long_first_doc_paragraph)]

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod avx2;
pub mod portable;
Expand Down
Loading
Loading