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

Runtime gas meter #2838

Merged
merged 25 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e6ef593
Removes whitelisted gas and sets a constant for the runtime gas meter
grarco Mar 7, 2024
592981c
Gas for ibc tx and removes unused host fn for whitelisted gas
grarco Mar 7, 2024
4571652
Adds unit tests for out of gas
grarco Mar 7, 2024
bbec083
Changes docstrings for signature verification
grarco Mar 7, 2024
e46164b
Adds wasm opcodes benchmarks
grarco Mar 8, 2024
a1a76ec
Benchmarks for shielded actions
grarco Mar 9, 2024
3d979c8
Removes benchmark for vp validator
grarco Mar 9, 2024
feed8ee
Clippy + fmt
grarco Mar 9, 2024
e811ead
Removes testing dependency from the benchmarks crate
grarco Mar 9, 2024
d256359
Updates masp vp checks
grarco Mar 10, 2024
84eee96
Higher resolution gas metering for masp
grarco Mar 10, 2024
aecad82
Fixes make clippy for benchmarks
grarco Mar 10, 2024
e71add1
Updates beatch size for benchmarks
grarco Mar 12, 2024
fc2d769
Renames vp user benchmark
grarco Mar 12, 2024
ec2f97b
Removes old comment
grarco Mar 14, 2024
217c354
Iterations and improvements for wasm opcodes benchmarks
grarco Mar 14, 2024
dff2cb1
Singlepass compiler for wasm benchmarks
grarco Mar 17, 2024
75859ff
Updates gas costs
grarco Mar 17, 2024
bdf62dd
Gas metering in `PseudoExecutionContext`
grarco Mar 18, 2024
571dba2
Increases gas scale
grarco Mar 18, 2024
e225cb5
Increases gas limits in unit tests
grarco Mar 18, 2024
d591d3c
Changelog #2838
grarco Mar 18, 2024
937682f
Adds source for wasm gas costs
grarco Mar 20, 2024
57cb950
Empty loop in out of gas unit tests
grarco Mar 25, 2024
eb302a8
Test that native VPs correctly run out of gas
sug0 Mar 21, 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
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/2838-runtime-gas-meter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Improved the gas metering system to track gas at runtime in wasm.
([\#2838](https://github.com/anoma/namada/pull/2838))
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ tracing-appender = "0.2.2"
tracing-log = "0.1.2"
tracing-subscriber = {version = "0.3.7", default-features = false, features = ["env-filter", "fmt"]}
wasmparser = "0.107.0"
wasm-instrument = {version = "0.4.0", features = ["sign_ext"]}
wasmer = {git = "https://github.com/heliaxdev/wasmer", rev = "255054f7f58b7b4a525f2fee6b9b86422d1ca15b"}
wasmer-compiler-singlepass = { git = "https://github.com/heliaxdev/wasmer", rev = "255054f7f58b7b4a525f2fee6b9b86422d1ca15b" }
wasmer-engine-universal = { git = "https://github.com/heliaxdev/wasmer", rev = "255054f7f58b7b4a525f2fee6b9b86422d1ca15b" }
winapi = "0.3.9"
yansi = "0.5.1"
zeroize = { version = "1.5.5", features = ["zeroize_derive"] }
Expand Down
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,10 @@ check-crates:

clippy-wasm = $(cargo) +$(nightly) clippy --manifest-path $(wasm)/Cargo.toml --all-targets -- -D warnings

# Need a separate command for benchmarks to prevent the "testing" feature flag from being activated
clippy:
$(cargo) +$(nightly) clippy $(jobs) --all-targets -- -D warnings && \
$(cargo) +$(nightly) clippy $(jobs) --all-targets --workspace --exclude namada_benchmarks -- -D warnings && \
$(cargo) +$(nightly) clippy $(jobs) --all-targets --package namada_benchmarks -- -D warnings && \
make -C $(wasms) clippy && \
make -C $(wasms_for_tests) clippy && \
$(foreach wasm,$(wasm_templates),$(clippy-wasm) && ) true
Expand Down Expand Up @@ -261,7 +263,7 @@ clean:
$(cargo) clean

bench:
$(cargo) bench --package namada_benchmarks
$(cargo) bench --package namada_benchmarks

build-doc:
$(cargo) doc --no-deps
Expand Down
2 changes: 1 addition & 1 deletion crates/apps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ mainnet = [
]
# for integration tests and test utilities
testing = ["namada_test_utils"]
benches = ["testing", "namada_test_utils"]
benches = ["namada_test_utils"]
integration = []
jemalloc = ["rocksdb/jemalloc"]

Expand Down
84 changes: 78 additions & 6 deletions crates/apps/src/lib/bench_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
use namada::ibc::primitives::proto::{Any, Protobuf};
use namada::ibc::primitives::{Msg, Timestamp as IbcTimestamp};
use namada::ibc::storage::port_key;
use namada::ibc::{IbcShieldedTransfer, MsgShieldedTransfer};
use namada::io::StdIo;
use namada::ledger::dry_run_tx;
use namada::ledger::gas::TxGasMeter;
Expand Down Expand Up @@ -329,7 +330,7 @@
tx
}

pub fn generate_ibc_tx(&self, wasm_code_path: &str, msg: impl Msg) -> Tx {
pub fn generate_ibc_tx(&self, wasm_code_path: &str, msg: Vec<u8>) -> Tx {

Check warning on line 333 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L333

Added line #L333 was not covered by tests
// This function avoid serializaing the tx data with Borsh
let mut tx = Tx::from_type(namada::tx::data::TxType::Decrypted(
namada::tx::data::DecryptedTx::Decrypted,
Expand All @@ -341,10 +342,7 @@
code_hash,
Some(wasm_code_path.to_string()),
));

let mut data = vec![];
prost::Message::encode(&msg.to_any(), &mut data).unwrap();
tx.set_data(Data::new(data));
tx.set_data(Data::new(msg));

Check warning on line 345 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L345

Added line #L345 was not covered by tests

// NOTE: the Ibc VP doesn't actually check the signature
tx
Expand Down Expand Up @@ -384,7 +382,10 @@
timeout_timestamp_on_b: timeout_timestamp,
};

self.generate_ibc_tx(TX_IBC_WASM, msg)
let mut data = vec![];
prost::Message::encode(&msg.to_any(), &mut data).unwrap();

self.generate_ibc_tx(TX_IBC_WASM, data)

Check warning on line 388 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L385-L388

Added lines #L385 - L388 were not covered by tests
}

pub fn execute_tx(&mut self, tx: &Tx) {
Expand Down Expand Up @@ -560,6 +561,11 @@
.unwrap();

self.inner.commit();
self.inner
.state
.in_mem_mut()
.set_header(get_dummy_header())
.unwrap();

Check warning on line 568 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L564-L568

Added lines #L564 - L568 were not covered by tests
}

// Commit a masp transaction and cache the tx and the changed keys for
Expand Down Expand Up @@ -1070,4 +1076,70 @@
};
(ctx, tx)
}

pub fn generate_shielded_action(
self,
amount: Amount,
source: TransferSource,
target: TransferTarget,
) -> (Self, Tx) {
let (ctx, tx) = self.generate_masp_tx(
amount,
source.clone(),
TransferTarget::Address(Address::Internal(InternalAddress::Ibc)),
);

let token = PrefixedCoin {
denom: address::testing::nam().to_string().parse().unwrap(),
amount: amount
.to_string_native()
.split('.')
.next()
.unwrap()
.to_string()
.parse()
.unwrap(),
};
let timeout_height = TimeoutHeight::At(IbcHeight::new(0, 100).unwrap());

let now: namada::tendermint::Time =
DateTimeUtc::now().try_into().unwrap();
let now: IbcTimestamp = now.into();
let timeout_timestamp =
(now + std::time::Duration::new(3600, 0)).unwrap();
let msg = MsgTransfer {
port_id_on_a: PortId::transfer(),
chan_id_on_a: ChannelId::new(5),
packet_data: PacketData {
token,
sender: source.effective_address().to_string().into(),
receiver: target.effective_address().to_string().into(),
memo: "".parse().unwrap(),
},
timeout_height_on_b: timeout_height,
timeout_timestamp_on_b: timeout_timestamp,
};

let transfer =
Transfer::deserialize(&mut tx.data().unwrap().as_slice()).unwrap();
let masp_tx = tx
.get_section(&transfer.shielded.unwrap())
.unwrap()
.masp_tx()
.unwrap();
let msg = MsgShieldedTransfer {
message: msg,
shielded_transfer: IbcShieldedTransfer {
transfer,
masp_tx: masp_tx.clone(),
},
};

let mut ibc_tx = ctx
.shell
.generate_ibc_tx(TX_IBC_WASM, msg.serialize_to_vec());
ibc_tx.add_masp_tx_section(masp_tx);

(ctx, ibc_tx)
}

Check warning on line 1144 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L1080-L1144

Added lines #L1080 - L1144 were not covered by tests
}
2 changes: 1 addition & 1 deletion crates/apps/src/lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(rustdoc::private_intra_doc_links)]

#[cfg(feature = "testing")]
#[cfg(feature = "benches")]
pub mod bench_utils;
pub mod cli;
pub mod client;
Expand Down
6 changes: 5 additions & 1 deletion crates/apps/src/lib/node/ledger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@
tracing::debug!("Request InitChain");
self.init_chain(
init,
#[cfg(any(test, feature = "testing"))]
#[cfg(any(
test,
feature = "testing",
feature = "benches"
))]

Check warning on line 106 in crates/apps/src/lib/node/ledger/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/node/ledger/mod.rs#L102-L106

Added lines #L102 - L106 were not covered by tests
1,
)
.map(Response::InitChain)
Expand Down
35 changes: 15 additions & 20 deletions crates/apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,8 @@ mod test_finalize_block {
FinalizeBlock, ProcessedTx,
};

const GAS_LIMIT_MULTIPLIER: u64 = 100_000_000;
const GAS_LIMIT: u64 = 10_000_000_000;
const WRAPPER_GAS_LIMIT: u64 = 20_000;

/// Make a wrapper tx and a processed tx from the wrapped tx that can be
/// added to `FinalizeBlock` request.
Expand All @@ -816,7 +817,7 @@ mod test_finalize_block {
},
keypair.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
wrapper_tx.header.chain_id = shell.chain_id.clone();
Expand Down Expand Up @@ -857,7 +858,7 @@ mod test_finalize_block {
},
keypair.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
outer_tx.header.chain_id = shell.chain_id.clone();
Expand Down Expand Up @@ -973,7 +974,7 @@ mod test_finalize_block {
},
keypair.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
outer_tx.header.chain_id = shell.chain_id.clone();
Expand Down Expand Up @@ -1027,7 +1028,7 @@ mod test_finalize_block {
},
keypair.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
let processed_tx = ProcessedTx {
Expand Down Expand Up @@ -2758,7 +2759,7 @@ mod test_finalize_block {
},
keypair.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
wrapper.header.chain_id = shell.chain_id.clone();
Expand All @@ -2775,7 +2776,7 @@ mod test_finalize_block {
},
keypair_2.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
new_wrapper.add_section(Section::Signature(Signature::new(
Expand Down Expand Up @@ -2816,8 +2817,8 @@ mod test_finalize_block {
})
}

shell.enqueue_tx(wrapper.clone(), GAS_LIMIT_MULTIPLIER.into());
shell.enqueue_tx(new_wrapper.clone(), GAS_LIMIT_MULTIPLIER.into());
shell.enqueue_tx(wrapper.clone(), GAS_LIMIT.into());
shell.enqueue_tx(new_wrapper.clone(), GAS_LIMIT.into());
// merkle tree root before finalize_block
let root_pre = shell.shell.state.in_mem().block.tree.root();

Expand Down Expand Up @@ -2884,7 +2885,7 @@ mod test_finalize_block {
},
keypair.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
unsigned_wrapper.header.chain_id = shell.chain_id.clone();
Expand Down Expand Up @@ -2965,16 +2966,10 @@ mod test_finalize_block {
}

shell.enqueue_tx(out_of_gas_wrapper.clone(), Gas::default());
shell.enqueue_tx(
undecryptable_wrapper.clone(),
GAS_LIMIT_MULTIPLIER.into(),
);
shell.enqueue_tx(undecryptable_wrapper.clone(), GAS_LIMIT.into());
shell.enqueue_tx(unsigned_wrapper.clone(), u64::MAX.into()); // Prevent out of gas which would still make the test pass
shell.enqueue_tx(
wrong_commitment_wrapper.clone(),
GAS_LIMIT_MULTIPLIER.into(),
);
shell.enqueue_tx(failing_wrapper.clone(), GAS_LIMIT_MULTIPLIER.into());
shell.enqueue_tx(wrong_commitment_wrapper.clone(), GAS_LIMIT.into());
shell.enqueue_tx(failing_wrapper.clone(), GAS_LIMIT.into());
// merkle tree root before finalize_block
let root_pre = shell.shell.state.in_mem().block.tree.root();

Expand Down Expand Up @@ -3138,7 +3133,7 @@ mod test_finalize_block {
},
keypair.ref_to(),
Epoch(0),
GAS_LIMIT_MULTIPLIER.into(),
WRAPPER_GAS_LIMIT.into(),
None,
))));
wrapper.header.chain_id = shell.chain_id.clone();
Expand Down
3 changes: 2 additions & 1 deletion crates/apps/src/lib/node/ledger/shell/init_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ where
pub fn init_chain(
&mut self,
init: request::InitChain,
#[cfg(any(test, feature = "testing"))] _num_validators: u64,
#[cfg(any(test, feature = "testing", feature = "benches"))]
_num_validators: u64,
) -> Result<response::InitChain> {
let mut response = response::InitChain::default();
let chain_id = self.state.in_mem().chain_id.as_str();
Expand Down
14 changes: 13 additions & 1 deletion crates/benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,28 @@ name = "host_env"
harness = false
path = "host_env.rs"

[[bench]]
name = "wasm_opcodes"
harness = false
path = "wasm_opcodes.rs"

[dependencies]

# NOTE: this crate MUST NOT import any dependency with testing features to prevent benchmarking non-production code
[dev-dependencies]
namada = { path = "../namada", features = ["rand", "testing"] }
namada = { path = "../namada", features = ["rand", "benches"] }
namada_apps = { path = "../apps", features = ["benches"] }
masp_primitives.workspace = true
borsh.workspace = true
borsh-ext.workspace = true
criterion = { version = "0.5", features = ["html_reports"] }
lazy_static.workspace= true
prost.workspace = true
rand_core.workspace = true
rand.workspace = true
tempfile.workspace = true
sha2.workspace = true
wasm-instrument.workspace = true
wasmer-compiler-singlepass.workspace = true
wasmer-engine-universal.workspace = true
wasmer.workspace = true
Loading
Loading