diff --git a/CHANGES.md b/CHANGES.md
index 5eb3e76de..f12ec0c81 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [2.8.1] 2022-12-07
+
+### Changes
+
+- Performance improvement (approximately 5% reduction in NEAR gas usage) by [@birchmd]. ([#645])
+
+### Fixes
+
+- Tracing bug fix by [@birchmd]. ([#646])
+
+[#645]: https://github.com/aurora-is-near/aurora-engine/pull/645
+[#646]: https://github.com/aurora-is-near/aurora-engine/pull/646
+
## [2.8.0] 2022-11-15
### Added
@@ -321,7 +334,8 @@ struct SubmitResult {
## [1.0.0] - 2021-05-12
-[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/2.8.0...develop
+[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/2.8.1...develop
+[2.8.1]: https://github.com/aurora-is-near/aurora-engine/compare/2.8.0...2.8.1
[2.8.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.7.0...2.8.0
[2.7.0]: https://github.com/aurora-is-near/aurora-engine/compare/2.6.1...2.7.0
[2.6.1]: https://github.com/aurora-is-near/aurora-engine/compare/2.6.0...2.6.1
diff --git a/Cargo.lock b/Cargo.lock
index 1261e44f9..d321c1287 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -127,7 +127,7 @@ dependencies = [
[[package]]
name = "aurora-engine"
-version = "2.8.0"
+version = "2.8.1"
dependencies = [
"aurora-engine-precompiles",
"aurora-engine-sdk",
@@ -1318,7 +1318,7 @@ dependencies = [
[[package]]
name = "evm"
version = "0.37.0"
-source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.1-aurora#12a268120c0f6d4b3c3f35043e7f9482e7a6fd43"
+source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.3-aurora#ad17d1c242356e25692573a5eea4b50ee80f6de3"
dependencies = [
"auto_impl",
"environmental",
@@ -1338,7 +1338,7 @@ dependencies = [
[[package]]
name = "evm-core"
version = "0.37.0"
-source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.1-aurora#12a268120c0f6d4b3c3f35043e7f9482e7a6fd43"
+source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.3-aurora#ad17d1c242356e25692573a5eea4b50ee80f6de3"
dependencies = [
"parity-scale-codec",
"primitive-types 0.12.1",
@@ -1349,7 +1349,7 @@ dependencies = [
[[package]]
name = "evm-gasometer"
version = "0.37.0"
-source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.1-aurora#12a268120c0f6d4b3c3f35043e7f9482e7a6fd43"
+source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.3-aurora#ad17d1c242356e25692573a5eea4b50ee80f6de3"
dependencies = [
"environmental",
"evm-core",
@@ -1360,7 +1360,7 @@ dependencies = [
[[package]]
name = "evm-runtime"
version = "0.37.0"
-source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.1-aurora#12a268120c0f6d4b3c3f35043e7f9482e7a6fd43"
+source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.37.3-aurora#ad17d1c242356e25692573a5eea4b50ee80f6de3"
dependencies = [
"auto_impl",
"environmental",
diff --git a/VERSION b/VERSION
index 834f26295..dbe590065 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.8.0
+2.8.1
diff --git a/engine-precompiles/Cargo.toml b/engine-precompiles/Cargo.toml
index 4e392d9ce..b5b57b9a5 100644
--- a/engine-precompiles/Cargo.toml
+++ b/engine-precompiles/Cargo.toml
@@ -17,7 +17,7 @@ aurora-engine-types = { path = "../engine-types", default-features = false }
aurora-engine-sdk = { path = "../engine-sdk", default-features = false }
borsh = { version = "0.9.3", default-features = false }
bn = { version = "0.5.11", package = "zeropool-bn", default-features = false }
-evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false }
+evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false }
libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context", "hmac"] }
num = { version = "0.4.0", default-features = false, features = ["alloc"] }
ripemd = { version = "0.1.1", default-features = false }
diff --git a/engine-standalone-storage/Cargo.toml b/engine-standalone-storage/Cargo.toml
index 866a62579..889e14d9f 100644
--- a/engine-standalone-storage/Cargo.toml
+++ b/engine-standalone-storage/Cargo.toml
@@ -20,7 +20,7 @@ aurora-engine-sdk = { path = "../engine-sdk", default-features = false, features
aurora-engine-transactions = { path = "../engine-transactions", default-features = false, features = ["std"] }
aurora-engine-precompiles = { path = "../engine-precompiles", default-features = false, features = ["std"] }
borsh = { version = "0.9.3" }
-evm-core = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false }
+evm-core = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false }
hex = "0.4.3"
rocksdb = { version = "0.19.0", default-features = false }
postgres = "0.19.2"
diff --git a/engine-standalone-tracing/Cargo.toml b/engine-standalone-tracing/Cargo.toml
index b7bfb8aa3..615da9d6e 100644
--- a/engine-standalone-tracing/Cargo.toml
+++ b/engine-standalone-tracing/Cargo.toml
@@ -15,10 +15,10 @@ crate-type = ["lib"]
[dependencies]
aurora-engine-types = { path = "../engine-types", default-features = false, features = ["std"] }
-evm-core = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std"] }
-evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
-evm-runtime = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
-evm-gasometer = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
+evm-core = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std"] }
+evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
+evm-runtime = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
+evm-gasometer = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
hex = { version = "0.4", default-features = false, features = ["std"] }
serde = { version = "1", features = ["derive"], optional = true }
diff --git a/engine-standalone-tracing/src/types/call_tracer.rs b/engine-standalone-tracing/src/types/call_tracer.rs
index 33a695525..e54ca22a1 100644
--- a/engine-standalone-tracing/src/types/call_tracer.rs
+++ b/engine-standalone-tracing/src/types/call_tracer.rs
@@ -5,21 +5,21 @@ use aurora_engine_types::{types::Address, U256};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CallFrame {
- call_type: CallType,
- from: Address,
- to: Option
,
- value: U256,
- gas: u64,
- gas_used: u64,
- input: Vec,
- output: Vec,
- error: Option,
- calls: Vec,
+ pub call_type: CallType,
+ pub from: Address,
+ pub to: Option,
+ pub value: U256,
+ pub gas: u64,
+ pub gas_used: u64,
+ pub input: Vec,
+ pub output: Vec,
+ pub error: Option,
+ pub calls: Vec,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct CallTracer {
- call_stack: Vec,
+ pub call_stack: Vec,
}
impl CallTracer {
@@ -163,10 +163,10 @@ impl evm::tracing::EventListener for CallTracer {
} => {
let call_type = if is_static {
CallType::StaticCall
- } else if transfer.is_none() {
- CallType::DelegateCall
} else if code_address == context.address {
CallType::Call
+ } else if transfer.is_none() {
+ CallType::DelegateCall
} else {
CallType::CallCode
};
diff --git a/engine-test-doubles/Cargo.toml b/engine-test-doubles/Cargo.toml
index 54de5edd7..10e29048a 100644
--- a/engine-test-doubles/Cargo.toml
+++ b/engine-test-doubles/Cargo.toml
@@ -15,8 +15,8 @@ autobenches = false
[dependencies]
aurora-engine-types = { path = "../engine-types", default-features = false, features = ["std"] }
aurora-engine-sdk = { path = "../engine-sdk" }
-evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
-evm-runtime = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
-evm-gasometer = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
+evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
+evm-runtime = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
+evm-gasometer = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
[dev-dependencies]
diff --git a/engine-tests/Cargo.toml b/engine-tests/Cargo.toml
index 4a551162e..43da94dd9 100644
--- a/engine-tests/Cargo.toml
+++ b/engine-tests/Cargo.toml
@@ -22,12 +22,12 @@ aurora-engine-sdk = { path = "../engine-sdk", default-features = false, features
aurora-engine-precompiles = { path = "../engine-precompiles", default-features = false, features = ["std"] }
aurora-engine-transactions = { path = "../engine-transactions", default-features = false, features = ["std"] }
engine-standalone-storage = { path = "../engine-standalone-storage" }
-engine-standalone-tracing = { path = "../engine-standalone-tracing" }
+engine-standalone-tracing = { path = "../engine-standalone-tracing", default-features = false, features = ["impl-serde"] }
borsh = { version = "0.9.3", default-features = false }
sha3 = { version = "0.10.2", default-features = false }
-evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
-evm-runtime = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
-evm-gasometer = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false, features = ["std", "tracing"] }
+evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
+evm-runtime = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
+evm-gasometer = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false, features = ["std", "tracing"] }
rlp = { version = "0.5.0", default-features = false }
base64 = "0.13.0"
bstr = "1.0.1"
diff --git a/engine-tests/src/test_utils/standalone/mod.rs b/engine-tests/src/test_utils/standalone/mod.rs
index 43e30b2ea..927e2d624 100644
--- a/engine-tests/src/test_utils/standalone/mod.rs
+++ b/engine-tests/src/test_utils/standalone/mod.rs
@@ -317,7 +317,7 @@ impl StandaloneRunner {
self.storage_dir.close().unwrap();
}
- fn template_tx_msg(
+ pub(crate) fn template_tx_msg(
storage: &mut Storage,
env: &env::Fixed,
transaction_position: u16,
diff --git a/engine-tests/src/tests/mod.rs b/engine-tests/src/tests/mod.rs
index 30f18d30e..741e56ae8 100644
--- a/engine-tests/src/tests/mod.rs
+++ b/engine-tests/src/tests/mod.rs
@@ -22,4 +22,4 @@ mod standalone;
mod standard_precompiles;
mod state_migration;
pub(crate) mod uniswap;
-mod xcc;
+pub(crate) mod xcc;
diff --git a/engine-tests/src/tests/one_inch.rs b/engine-tests/src/tests/one_inch.rs
index 63581b3c7..b1f4d388f 100644
--- a/engine-tests/src/tests/one_inch.rs
+++ b/engine-tests/src/tests/one_inch.rs
@@ -58,7 +58,7 @@ fn test_1inch_liquidity_protocol() {
},
);
assert!(result.gas_used >= 302_000); // more than 302k EVM gas used
- assert_gas_bound(profile.all_gas(), 24);
+ assert_gas_bound(profile.all_gas(), 23);
// Same here
helper.runner.context.block_timestamp += 10_000_000 * 1_000_000_000;
@@ -73,7 +73,7 @@ fn test_1inch_liquidity_protocol() {
},
);
assert!(result.gas_used >= 210_000); // more than 210k EVM gas used
- assert_gas_bound(profile.all_gas(), 25);
+ assert_gas_bound(profile.all_gas(), 24);
let (result, profile) = helper.pool_withdraw(
&pool,
@@ -84,7 +84,7 @@ fn test_1inch_liquidity_protocol() {
},
);
assert!(result.gas_used >= 150_000); // more than 150k EVM gas used
- assert_gas_bound(profile.all_gas(), 21);
+ assert_gas_bound(profile.all_gas(), 20);
}
#[test]
diff --git a/engine-tests/src/tests/repro.rs b/engine-tests/src/tests/repro.rs
index fc4be898f..1370a7cf9 100644
--- a/engine-tests/src/tests/repro.rs
+++ b/engine-tests/src/tests/repro.rs
@@ -27,7 +27,7 @@ fn repro_GdASJ3KESs() {
block_timestamp: 1645717564644206730,
input_path: "src/tests/res/input_GdASJ3KESs.hex",
evm_gas_used: 706713,
- near_gas_used: 131,
+ near_gas_used: 122,
});
}
@@ -52,7 +52,7 @@ fn repro_8ru7VEA() {
block_timestamp: 1648829935343349589,
input_path: "src/tests/res/input_8ru7VEA.hex",
evm_gas_used: 1732181,
- near_gas_used: 239,
+ near_gas_used: 223,
});
}
@@ -72,7 +72,7 @@ fn repro_FRcorNv() {
block_timestamp: 1650960438774745116,
input_path: "src/tests/res/input_FRcorNv.hex",
evm_gas_used: 1239721,
- near_gas_used: 194,
+ near_gas_used: 181,
});
}
@@ -89,7 +89,7 @@ fn repro_5bEgfRQ() {
block_timestamp: 1651073772931594646,
input_path: "src/tests/res/input_5bEgfRQ.hex",
evm_gas_used: 6_414_105,
- near_gas_used: 701,
+ near_gas_used: 657,
});
}
@@ -107,7 +107,7 @@ fn repro_D98vwmi() {
block_timestamp: 1651753443421003245,
input_path: "src/tests/res/input_D98vwmi.hex",
evm_gas_used: 1_035_348,
- near_gas_used: 195,
+ near_gas_used: 182,
});
}
@@ -126,7 +126,7 @@ fn repro_Emufid2() {
block_timestamp: 1662118048636713538,
input_path: "src/tests/res/input_Emufid2.hex",
evm_gas_used: 1_156_364,
- near_gas_used: 330,
+ near_gas_used: 306,
});
}
diff --git a/engine-tests/src/tests/sanity.rs b/engine-tests/src/tests/sanity.rs
index eae9b9a00..fb51786bd 100644
--- a/engine-tests/src/tests/sanity.rs
+++ b/engine-tests/src/tests/sanity.rs
@@ -453,6 +453,34 @@ fn test_call_too_deep_error() {
}
}
+#[test]
+fn test_create_out_of_gas() {
+ let (mut runner, mut signer, _) = initialize_transfer();
+ let constructor_code = {
+ // This EVM bytecode caused an integer overflow in the SputnikVM gas calculation prior to
+ // https://github.com/aurora-is-near/sputnikvm/pull/17
+ let code = "60e041184138410745413205374848484848484848484848484848484848484848484541384107456969697835ffff004545453a4747f06262483b646464645454543030303030303030303030303030303030303030303136383432353936337a5a5a8154543838929260545454545454545454315555555555555555555a5a5a5a5a5a5a5a3d5a615a5a5a5a5a455858580153455858585801825858828282545360305858586158f05858f05830303030303030303136383431353936337a5a5a8154543838929260545454545454545454315555555d55555555555a5a5a5a5a5a5a5a5a5a5a5a5a5a5a4558585801534558585858018258588282825453601558583158183d60253d60013a58f08258853480f07e82823aabac9fcdcea7a758583d6015315858585858f058585860253d60013a3d381a3d3361333030305858586158f05858f0583af00133303030828258588282825453601531585858583d60253d60013a58f08258853580f03a82827eab3d4343468546464646464646464646836500838311111111111111111111837676767676765a5a1515fb41151514742393f0555555555555555555555555555555555555555555555555555555555555555a5a5a5a5a5a455858580153455858585801827676765a5a1515fb41151514742393f055555555555555555555554558585801534558585858018258588282825453601531585858183d60253d60013a5858853580f03a82827eab3d9fcdcea7a75858fe3d60153f484848c40200000000000034483b325885858585858585853d60013a58f08261333030305858853580f03a82827eab30ac9fcdcea7a758583d6085853d60013a58f08261333060253d5e013a3d381a3d3361333030305858586158f05858f0583af001333030308282585882828254535a1531585858583d60253d60013a58f08258853580f03a82827eab3d9fcdcea7a758583d60153f484848483b323a4545314545353a4545450945317432454545304545304545303a4545314545353a45454509453174324545453045453a3a4545453a4545303a454530453a4545303a4545324545353a454545094531743a4546464646303a4545314545353a45454509453174324545453045453a3a4545453a4545303a454530453a4545303a4545314545353a4545450945317432454545304545304545303a4545314545353a45454509453174324545453045453a3a4545453a4545303a454530453a4545303a4545324545353a454545094531743a4546464619464646464646464646464646464646464646468258588282825453601531585858183d60253d60013a58f08258853580f03a828255555555555555555555555555555555555555555555555555556b6b6b6b3a5a3a4447474747f045456464ae646464646464646c6464325858435858013658584337585843015836585858384358585858f15858f158585885854085855858f15858f158580136585843375858430158f1585836585843385843385858013658584337585843015836585843585843385843385858013658584337585843015836585843385858585858f15858f158585858f15858f15858385858585858f15858f1585858f158585858f1585836585843385843385858365858015858433758f15858385858585858f15858f1585858f158585858f158583658584338584338585801365858489292605454545454545454543030303030303030303030303030303030303030303136383431353936337a5a5a8154543838929260545454545454545454315555555555555555555a5a5a5a5a5a5a5a5a5a5a5a413205374848484848484848484848484848484848485a6128a756455f07ef93f31ef468d3bc0d17e020b320616161616161616161616161616161616161616161616161515151515151070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070751515151484848485151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151518d616161616141364107454132053748484848484848489060604145614138415a07614541325a5a4558585801534558585858018258588282825453601531585858183d60253d60013a58f08258853480f07e82823aabac9fcdcea7a758583d6015315858585858f058585860253d60013a3d381a3d3361333030305858586158f05858f05830303030303030303136383431353936337a5a5a815454383892926054545454827676765a5a1515fb41151514742393f05555555555555555555555555555555555555555453a4747f04545646464646464646464646c6464643a474745343a4747f045454545453a4747f06262483b646464646464646464646c64646464646464646445646464646464646464646c6464646464646464f0305830303030343a36321a34347a36311a34347d34343a30282828282828282828282828282828282828282828282828282828282828a2a230340b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b050b0b0b3030303030303030303030303030303031353038323036333333333333333333333333333333333345304545304545303a4545314545353a45454509453174324545453045453a3a454506060606060606060606060606065050505050505050505050505050505050505050503361333030305858586158f05858f0581af00133303030828258588282825453601531585858583d60253d60013a58f28258853580f03a82827eab3d9fcdcea7a7464646464646464646464646462946464646464646464646464631707432454545304545353a4545453a4545303a4545304545353a453b32588585858585853a000000000000000000583f48383838486158f05858f0583af00133303030828258588282825453601531585858583d60253d60013a58f08258853580f03a82827eab3d9fcdcea7a758583d60153f484848483b32583f48d93838483b32586e858585858585585858f058585860253d5e013a3d381a3d33613330303058584358585858f15858f158585885854085855858f15858f158580136585843375858430158f1585836585843385843385858013658584337585843015836585843585843385843385858013658584337585843015836585843385858585858f15858f158585858f15858f15858385858585858f15858f1585858f158585858f1585836585843385843385858365858015858433758586158f05858f0583af00133305858586025603d013a3d381a5d3d3361050000003b325885b0bd02f6a392af548bdf1cfaee5dfa0eefcc8eab82827eabac9fcdcea7a758583dfeffffffffffffff6015000000000000000000000000ffffff303d389a3d603dff7effffffffffffff0600f15858385858585858f15858f1585858f158585858f158583658584338584338585801365858489292605454545454545454543030303030303030303030303030303030303030303136383431353936337a5a5a8154543838929260545454545454545454315555555555555555555a5a5a5a5a5affffffffffffffffffffffffffffffffffffffffffffffffffff5a5a5a5a5a5a5a5a5a4558585801534558585858018258588282825453601531585858183d60253d60013a58f08258853480f07e82823aabac9fcdcea7a758583d6015315858580000f70000000037201616355858f058585860253d60013a3d381a3d336133303030585851586158f05858f05830303030303030303136383431353936337a5a5a8154543838929260545454545454545454315555555555555555555a5a5a325a5a5a5a5a5a5a5a5a5a5a5a4558585801534558585858018258588282825453601558583158183d60253d60013a58f08258853480f07e82823aabac000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009fcdcea7a758583d6015315858585858f058585860253d60013a3d381a3d3361333030305858586158f05858f0583af0013330303082825858828282545360153155555555555555555555555a5a5a5a5a5a4558585843468546464646464646464646838383111111111111111111ffff11837676767676765a5a1515fb41151514742393f0555555555555555555555555555555555555555555555555555555555555555a5a5a5a5a5a455858580153455858585801827676765a5a1515fb41151516742393f055555555555555555555555562483b45454545ff3a4747f06262483b4545454545453a47474745343a4747f045454555555555555555555555555555553d3d838311111111111111111111837676767676765a5a1515fb41151514742393f055483f3f453f484848483b32583f48383838483b3258858561616161616161616161616161616161615555555555555555555555555555555555555555555555556155555555618255555a82";
+ hex::decode(code).unwrap()
+ };
+ let result = runner
+ .submit_with_signer(&mut signer, |nonce| {
+ aurora_engine_transactions::legacy::TransactionLegacy {
+ nonce,
+ gas_price: U256::zero(),
+ gas_limit: u64::MAX.into(),
+ to: None,
+ value: Wei::zero(),
+ data: constructor_code,
+ }
+ })
+ .unwrap();
+ assert!(
+ matches!(result.status, TransactionStatus::OutOfGas),
+ "Unexpected status: {:?}",
+ result.status
+ );
+}
+
#[test]
fn test_timestamp() {
let (mut runner, mut signer, _) = initialize_transfer();
diff --git a/engine-tests/src/tests/standalone/call_tracer.rs b/engine-tests/src/tests/standalone/call_tracer.rs
new file mode 100644
index 000000000..64669f08f
--- /dev/null
+++ b/engine-tests/src/tests/standalone/call_tracer.rs
@@ -0,0 +1,350 @@
+use crate::test_utils::{self, standalone};
+use aurora_engine_types::{
+ parameters::{CrossContractCallArgs, PromiseArgs, PromiseCreateArgs},
+ storage,
+ types::{Address, NearGas, Wei, Yocto},
+ U256,
+};
+use borsh::BorshSerialize;
+use engine_standalone_storage::sync;
+use engine_standalone_tracing::{
+ sputnik,
+ types::call_tracer::{self, CallTracer},
+};
+
+#[test]
+fn test_trace_precompile_direct_call() {
+ let mut runner = standalone::StandaloneRunner::default();
+ let mut signer = test_utils::Signer::random();
+
+ runner.init_evm();
+
+ let tx = aurora_engine_transactions::legacy::TransactionLegacy {
+ nonce: signer.use_nonce().into(),
+ gas_price: U256::zero(),
+ gas_limit: u64::MAX.into(),
+ to: Some(aurora_engine_precompiles::random::RandomSeed::ADDRESS),
+ value: Wei::zero(),
+ data: Vec::new(),
+ };
+
+ let mut listener = CallTracer::default();
+ let standalone_result = sputnik::traced_call(&mut listener, || {
+ runner.submit_transaction(&signer.secret_key, tx).unwrap()
+ });
+ assert!(standalone_result.status.is_ok());
+ assert_eq!(listener.call_stack.len(), 1);
+
+ let trace = listener.call_stack.pop().unwrap();
+
+ let expected_trace = call_tracer::CallFrame {
+ call_type: call_tracer::CallType::Call,
+ from: test_utils::address_from_secret_key(&signer.secret_key),
+ to: Some(aurora_engine_precompiles::random::RandomSeed::ADDRESS),
+ value: U256::zero(),
+ gas: u64::MAX,
+ gas_used: 21000_u64,
+ input: Vec::new(),
+ output: [0u8; 32].to_vec(),
+ error: None,
+ calls: Vec::new(),
+ };
+
+ assert_eq!(trace, expected_trace);
+
+ runner.close();
+}
+
+#[test]
+fn test_trace_contract_single_call() {
+ let mut runner = standalone::StandaloneRunner::default();
+ let mut signer = test_utils::Signer::random();
+ let signer_address = test_utils::address_from_secret_key(&signer.secret_key);
+
+ runner.init_evm();
+
+ let constructor = test_utils::erc20::ERC20Constructor::load();
+ let deploy_tx = constructor.deploy("Test", "TST", signer.use_nonce().into());
+ let deploy_result = runner
+ .submit_transaction(&signer.secret_key, deploy_tx)
+ .unwrap();
+ let contract_address = {
+ let bytes = test_utils::unwrap_success_slice(&deploy_result);
+ Address::try_from_slice(bytes).unwrap()
+ };
+ let contract = test_utils::erc20::ERC20(constructor.0.deployed_at(contract_address));
+
+ let tx = contract.balance_of(signer_address, signer.use_nonce().into());
+ let mut listener = CallTracer::default();
+ let standalone_result = sputnik::traced_call(&mut listener, || {
+ runner
+ .submit_transaction(&signer.secret_key, tx.clone())
+ .unwrap()
+ });
+ assert!(standalone_result.status.is_ok());
+ assert_eq!(listener.call_stack.len(), 1);
+
+ let trace = listener.call_stack.pop().unwrap();
+
+ let expected_trace = call_tracer::CallFrame {
+ call_type: call_tracer::CallType::Call,
+ from: signer_address,
+ to: Some(contract_address),
+ value: U256::zero(),
+ gas: u64::MAX,
+ gas_used: trace.gas_used,
+ input: tx.data,
+ output: [0u8; 32].to_vec(),
+ error: None,
+ calls: Vec::new(),
+ };
+
+ assert_eq!(trace, expected_trace);
+
+ runner.close();
+}
+
+#[test]
+fn test_trace_contract_with_sub_call() {
+ use crate::tests::uniswap::UniswapTestContext;
+ const MINT_AMOUNT: u64 = 1_000_000_000_000;
+ const LIQUIDITY_AMOUNT: u64 = MINT_AMOUNT / 5;
+ const OUTPUT_AMOUNT: u64 = LIQUIDITY_AMOUNT / 100;
+
+ let mut context = UniswapTestContext::new("uniswap");
+ let (token_a, token_b) = context.create_token_pair(MINT_AMOUNT.into());
+ let pool = context.create_pool(&token_a, &token_b);
+
+ let (_result, _profile) =
+ context.add_equal_liquidity(LIQUIDITY_AMOUNT.into(), &token_a, &token_b);
+
+ context.approve_erc20(&token_a, context.swap_router.0.address, U256::MAX);
+ context.approve_erc20(&token_b, context.swap_router.0.address, U256::MAX);
+ let params = context.exact_output_single_params(OUTPUT_AMOUNT.into(), &token_a, &token_b);
+
+ let mut listener = CallTracer::default();
+ let (_amount_in, _profile) = sputnik::traced_call(&mut listener, || {
+ context
+ .runner
+ .submit_with_signer_profiled(&mut context.signer, |nonce| {
+ context.swap_router.exact_output_single(params, nonce)
+ })
+ .unwrap()
+ });
+
+ assert_eq!(listener.call_stack.len(), 1);
+
+ let user_address = test_utils::address_from_secret_key(&context.signer.secret_key);
+ let router_address = context.swap_router.0.address;
+ let pool_address = pool.0.address;
+ let b_address = token_b.0.address;
+ let a_address = token_a.0.address;
+
+ // Call flow:
+ // User -> Router.exactOutputSingle -> Pool.swap -> B.transfer
+ // -> A.balanceOf
+ // -> Router.uniswapV3SwapCallback -> A.transferFrom
+ // -> A.balanceOf
+ let root_call = listener.call_stack.first().unwrap();
+ assert_eq!(root_call.from, user_address);
+ assert_eq!(root_call.to.unwrap(), router_address);
+
+ let call = subcall_lense(root_call, &[0]);
+ assert_eq!(call.from, router_address);
+ assert_eq!(call.to.unwrap(), pool_address);
+
+ let call = subcall_lense(root_call, &[0, 0]);
+ assert_eq!(call.from, pool_address);
+ assert_eq!(call.to.unwrap(), b_address);
+
+ let call = subcall_lense(root_call, &[0, 1]);
+ assert_eq!(call.from, pool_address);
+ assert_eq!(call.to.unwrap(), a_address);
+
+ let call = subcall_lense(root_call, &[0, 2]);
+ assert_eq!(call.from, pool_address);
+ assert_eq!(call.to.unwrap(), router_address);
+
+ let call = subcall_lense(root_call, &[0, 2, 0]);
+ assert_eq!(call.from, router_address);
+ assert_eq!(call.to.unwrap(), a_address);
+
+ let call = subcall_lense(root_call, &[0, 3]);
+ assert_eq!(call.from, pool_address);
+ assert_eq!(call.to.unwrap(), a_address);
+}
+
+#[test]
+fn test_trace_contract_with_precompile_sub_call() {
+ let mut runner = standalone::StandaloneRunner::default();
+ let mut signer = test_utils::Signer::random();
+
+ runner.init_evm();
+
+ let constructor = test_utils::standard_precompiles::PrecompilesConstructor::load();
+ let deploy_tx = constructor.deploy(signer.use_nonce().into());
+ let deploy_result = runner
+ .submit_transaction(&signer.secret_key, deploy_tx)
+ .unwrap();
+ let contract_address = {
+ let bytes = test_utils::unwrap_success_slice(&deploy_result);
+ Address::try_from_slice(bytes).unwrap()
+ };
+ let contract = test_utils::standard_precompiles::PrecompilesContract(
+ constructor.0.deployed_at(contract_address),
+ );
+
+ // This transaction calls the standard precompiles (`ecrecover`, `sha256`, etc) one aft the other.
+ // So the trace is one top-level call with multiple sub-calls (and the sub-calls contain no further sub-calls).
+ let tx = contract.call_method("test_all", signer.use_nonce().into());
+ let mut listener = CallTracer::default();
+ let standalone_result = sputnik::traced_call(&mut listener, || {
+ runner
+ .submit_transaction(&signer.secret_key, tx.clone())
+ .unwrap()
+ });
+ assert!(standalone_result.status.is_ok());
+ assert_eq!(listener.call_stack.len(), 1);
+
+ let trace = listener.call_stack.pop().unwrap();
+ assert_eq!(trace.calls.len(), 8);
+ for call in trace.calls {
+ assert!(call.calls.is_empty());
+ }
+
+ runner.close();
+}
+
+#[test]
+fn test_trace_precompiles_with_subcalls() {
+ // The XCC precompile does internal sub-calls. We will trace an XCC call.
+
+ let mut runner = standalone::StandaloneRunner::default();
+ let mut signer = test_utils::Signer::random();
+ let signer_address = test_utils::address_from_secret_key(&signer.secret_key);
+ let xcc_address = aurora_engine_precompiles::xcc::cross_contract_call::ADDRESS;
+
+ runner.init_evm();
+
+ // Deploy an ERC-20 contract to act as wNEAR. It doesn't actually need to be bridged for
+ // this test because we are not executing any scheduled promises.
+ let constructor = test_utils::erc20::ERC20Constructor::load();
+ let deploy_tx = constructor.deploy("wNEAR", "WNEAR", signer.use_nonce().into());
+ let deploy_result = runner
+ .submit_transaction(&signer.secret_key, deploy_tx)
+ .unwrap();
+ let wnear_address = {
+ let bytes = test_utils::unwrap_success_slice(&deploy_result);
+ Address::try_from_slice(bytes).unwrap()
+ };
+ let wnear = test_utils::erc20::ERC20(constructor.0.deployed_at(wnear_address));
+ let mint_tx = wnear.mint(signer_address, u128::MAX.into(), signer.use_nonce().into());
+ runner
+ .submit_transaction(&signer.secret_key, mint_tx)
+ .unwrap();
+ let approve_tx = wnear.approve(xcc_address, U256::MAX, signer.use_nonce().into());
+ runner
+ .submit_transaction(&signer.secret_key, approve_tx)
+ .unwrap();
+ // Ensure the above ERC-20 token is registered as if it were a bridged token
+ {
+ runner.env.block_height += 1;
+ let storage = &mut runner.storage;
+ let env = &runner.env;
+
+ let mut tx =
+ standalone::StandaloneRunner::template_tx_msg(storage, env, 0, Default::default(), &[]);
+ tx.transaction = sync::types::TransactionKind::DeployErc20(
+ aurora_engine::parameters::DeployErc20TokenArgs {
+ nep141: "wrap.near".parse().unwrap(),
+ },
+ );
+ let mut outcome = sync::execute_transaction_message(storage, tx).unwrap();
+ let key = storage::bytes_to_key(storage::KeyPrefix::Nep141Erc20Map, b"wrap.near");
+ outcome.diff.modify(key, wnear_address.as_bytes().to_vec());
+ let key =
+ storage::bytes_to_key(storage::KeyPrefix::Erc20Nep141Map, wnear_address.as_bytes());
+ outcome.diff.modify(key, b"wrap.near".to_vec());
+ test_utils::standalone::storage::commit(storage, &outcome);
+ }
+
+ // Setup xcc precompile in standalone runner
+ let xcc_router_bytes = crate::tests::xcc::contract_bytes();
+ let factory_update = {
+ runner.env.block_height += 1;
+ runner.env.predecessor_account_id = "aurora".parse().unwrap();
+ runner.env.signer_account_id = "aurora".parse().unwrap();
+ let storage = &mut runner.storage;
+ let env = &runner.env;
+
+ let mut tx =
+ standalone::StandaloneRunner::template_tx_msg(storage, env, 0, Default::default(), &[]);
+ tx.transaction = sync::types::TransactionKind::FactoryUpdate(xcc_router_bytes);
+ tx
+ };
+ let outcome = sync::execute_transaction_message(&runner.storage, factory_update).unwrap();
+ test_utils::standalone::storage::commit(&mut runner.storage, &outcome);
+ let set_wnear_address = {
+ runner.env.block_height += 1;
+ let storage = &mut runner.storage;
+ let env = &runner.env;
+
+ let mut tx =
+ standalone::StandaloneRunner::template_tx_msg(storage, env, 0, Default::default(), &[]);
+ tx.transaction = sync::types::TransactionKind::FactorySetWNearAddress(wnear_address);
+ tx
+ };
+ let outcome = sync::execute_transaction_message(&runner.storage, set_wnear_address).unwrap();
+ test_utils::standalone::storage::commit(&mut runner.storage, &outcome);
+
+ // User calls XCC precompile
+ let promise = PromiseCreateArgs {
+ target_account_id: "some_account.near".parse().unwrap(),
+ method: "whatever".into(),
+ args: Vec::new(),
+ attached_balance: Yocto::new(1),
+ attached_gas: NearGas::new(100_000_000_000_000),
+ };
+ let xcc_args = CrossContractCallArgs::Delayed(PromiseArgs::Create(promise));
+ let tx = aurora_engine_transactions::legacy::TransactionLegacy {
+ nonce: signer.use_nonce().into(),
+ gas_price: U256::zero(),
+ gas_limit: u64::MAX.into(),
+ to: Some(xcc_address),
+ value: Wei::zero(),
+ data: xcc_args.try_to_vec().unwrap(),
+ };
+ let mut listener = CallTracer::default();
+ let standalone_result = sputnik::traced_call(&mut listener, || {
+ runner
+ .submit_transaction(&signer.secret_key, tx.clone())
+ .unwrap()
+ });
+ assert!(standalone_result.status.is_ok());
+ assert_eq!(listener.call_stack.len(), 1);
+
+ let trace = listener.call_stack.pop().unwrap();
+ assert_eq!(trace.calls.len(), 1);
+ let subcall = trace.calls.first().unwrap();
+ assert_eq!(subcall.call_type, call_tracer::CallType::Call);
+ assert_eq!(subcall.from, xcc_address);
+ assert_eq!(subcall.to.unwrap(), wnear_address);
+ assert_eq!(U256::from_big_endian(&subcall.output), U256::one());
+
+ runner.close();
+}
+
+/// A convenience function for pulling out a sub-call from a trace.
+/// The `path` gives the index to pull out of each `calls` array.
+/// For example `path == []` simply returns the given `root`, while
+/// `path == [2, 0]` will return `root.calls[2].calls[0]`.
+fn subcall_lense<'a, 'b>(
+ root: &'a call_tracer::CallFrame,
+ path: &'b [usize],
+) -> &'a call_tracer::CallFrame {
+ let mut result = root;
+ for index in path {
+ result = result.calls.get(*index).unwrap();
+ }
+ result
+}
diff --git a/engine-tests/src/tests/standalone/mod.rs b/engine-tests/src/tests/standalone/mod.rs
index 6e3c6d728..17b037976 100644
--- a/engine-tests/src/tests/standalone/mod.rs
+++ b/engine-tests/src/tests/standalone/mod.rs
@@ -1,3 +1,4 @@
+mod call_tracer;
mod json_snapshot;
mod sanity;
mod storage;
diff --git a/engine-tests/src/tests/uniswap.rs b/engine-tests/src/tests/uniswap.rs
index c200b416c..7712f9ec5 100644
--- a/engine-tests/src/tests/uniswap.rs
+++ b/engine-tests/src/tests/uniswap.rs
@@ -38,7 +38,7 @@ fn test_uniswap_input_multihop() {
let (_amount_out, _evm_gas, profile) = context.exact_input(&tokens, INPUT_AMOUNT.into());
- assert_eq!(122, profile.all_gas() / 1_000_000_000_000);
+ assert_eq!(113, profile.all_gas() / 1_000_000_000_000);
}
#[test]
@@ -49,7 +49,7 @@ fn test_uniswap_exact_output() {
let (_result, profile) =
context.add_equal_liquidity(LIQUIDITY_AMOUNT.into(), &token_a, &token_b);
- test_utils::assert_gas_bound(profile.all_gas(), 33);
+ test_utils::assert_gas_bound(profile.all_gas(), 32);
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(
(40..=50).contains(&wasm_fraction),
@@ -59,7 +59,7 @@ fn test_uniswap_exact_output() {
let (_amount_in, profile) =
context.exact_output_single(&token_a, &token_b, OUTPUT_AMOUNT.into());
- test_utils::assert_gas_bound(profile.all_gas(), 18);
+ test_utils::assert_gas_bound(profile.all_gas(), 17);
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(
(45..=55).contains(&wasm_fraction),
diff --git a/engine-tests/src/tests/xcc.rs b/engine-tests/src/tests/xcc.rs
index ed05df32a..814986a23 100644
--- a/engine-tests/src/tests/xcc.rs
+++ b/engine-tests/src/tests/xcc.rs
@@ -816,7 +816,7 @@ fn approve_erc20(
assert!(approve_result.status.is_ok());
}
-fn contract_bytes() -> Vec {
+pub(crate) fn contract_bytes() -> Vec {
let base_path = Path::new("../etc").join("xcc-router");
let output_path = base_path.join("target/wasm32-unknown-unknown/release/xcc_router.wasm");
test_utils::rust::compile(base_path);
diff --git a/engine-transactions/Cargo.toml b/engine-transactions/Cargo.toml
index cfc821832..9a57b6d19 100644
--- a/engine-transactions/Cargo.toml
+++ b/engine-transactions/Cargo.toml
@@ -16,7 +16,7 @@ autobenches = false
aurora-engine-types = { path = "../engine-types", default-features = false }
aurora-engine-sdk = { path = "../engine-sdk", default-features = false }
aurora-engine-precompiles = { path = "../engine-precompiles", default-features = false }
-evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false }
+evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false }
rlp = { version = "0.5.0", default-features = false }
serde = { version = "1", features = ["derive"], optional = true }
diff --git a/engine/Cargo.toml b/engine/Cargo.toml
index 06b9d7cf6..15c8922fd 100644
--- a/engine/Cargo.toml
+++ b/engine/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "aurora-engine"
-version = "2.8.0"
+version = "2.8.1"
authors = ["Aurora Labs "]
edition = "2021"
description = ""
@@ -25,7 +25,7 @@ bitflags = { version = "1.3", default-features = false }
borsh = { version = "0.9.3", default-features = false }
byte-slice-cast = { version = "1.0", default-features = false }
ethabi = { version = "18.0", default-features = false }
-evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.1-aurora", default-features = false }
+evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.3-aurora", default-features = false }
hex = { version = "0.4", default-features = false, features = ["alloc"] }
rjson = { git = "https://github.com/aurora-is-near/rjson", rev = "cc3da949", default-features = false, features = ["integer"] }
rlp = { version = "0.5.0", default-features = false }