From d6b6e4854e320d15fe9776ee414ae9d98cf0c095 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 16 Aug 2023 11:00:16 +0200 Subject: [PATCH 1/6] Return full gas report --- libwasmvm/bindings.h | 44 +++++++++++++++++++++++++++---------- libwasmvm/src/calls.rs | 37 ++++++++++++++++--------------- libwasmvm/src/gas_report.rs | 24 ++++++++++++++++++++ libwasmvm/src/lib.rs | 2 ++ 4 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 libwasmvm/src/gas_report.rs diff --git a/libwasmvm/bindings.h b/libwasmvm/bindings.h index 60f301408..1f097dcec 100644 --- a/libwasmvm/bindings.h +++ b/libwasmvm/bindings.h @@ -342,6 +342,26 @@ typedef struct GoQuerier { struct Querier_vtable vtable; } GoQuerier; +typedef struct GasReport { + /** + * The original limit the instance was created with + */ + uint64_t limit; + /** + * The remaining gas that can be spend + */ + uint64_t remaining; + /** + * The amount of gas that was spend and metered externally in operations triggered by this instance + */ + uint64_t used_externally; + /** + * The amount of gas that was spend and metered internally (i.e. by executing Wasm and calling + * API methods which are not metered externally) + */ + uint64_t used_internally; +} GasReport; + struct cache_t *init_cache(struct ByteSliceView data_dir, struct ByteSliceView available_capabilities, uint32_t cache_size, @@ -391,7 +411,7 @@ struct UnmanagedVector instantiate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector execute(struct cache_t *cache, @@ -404,7 +424,7 @@ struct UnmanagedVector execute(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector migrate(struct cache_t *cache, @@ -416,7 +436,7 @@ struct UnmanagedVector migrate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector sudo(struct cache_t *cache, @@ -428,7 +448,7 @@ struct UnmanagedVector sudo(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector reply(struct cache_t *cache, @@ -440,7 +460,7 @@ struct UnmanagedVector reply(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector query(struct cache_t *cache, @@ -452,7 +472,7 @@ struct UnmanagedVector query(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_open(struct cache_t *cache, @@ -464,7 +484,7 @@ struct UnmanagedVector ibc_channel_open(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, @@ -476,7 +496,7 @@ struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_close(struct cache_t *cache, @@ -488,7 +508,7 @@ struct UnmanagedVector ibc_channel_close(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, @@ -500,7 +520,7 @@ struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, @@ -512,7 +532,7 @@ struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, @@ -524,7 +544,7 @@ struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector new_unmanaged_vector(bool nil, const uint8_t *ptr, uintptr_t length); diff --git a/libwasmvm/src/calls.rs b/libwasmvm/src/calls.rs index 520d2e1e5..c0f7f7a6d 100644 --- a/libwasmvm/src/calls.rs +++ b/libwasmvm/src/calls.rs @@ -18,6 +18,7 @@ use crate::error::{handle_c_error_binary, Error}; use crate::memory::{ByteSliceView, UnmanagedVector}; use crate::querier::GoQuerier; use crate::storage::GoStorage; +use crate::GasReport; fn into_backend(db: Db, api: GoApi, querier: GoQuerier) -> Backend { Backend { @@ -39,7 +40,7 @@ pub extern "C" fn instantiate( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_3_args( @@ -71,7 +72,7 @@ pub extern "C" fn execute( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_3_args( @@ -102,7 +103,7 @@ pub extern "C" fn migrate( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -132,7 +133,7 @@ pub extern "C" fn sudo( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -162,7 +163,7 @@ pub extern "C" fn reply( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -192,7 +193,7 @@ pub extern "C" fn query( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -222,7 +223,7 @@ pub extern "C" fn ibc_channel_open( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -252,7 +253,7 @@ pub extern "C" fn ibc_channel_connect( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -282,7 +283,7 @@ pub extern "C" fn ibc_channel_close( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -312,7 +313,7 @@ pub extern "C" fn ibc_packet_receive( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -342,7 +343,7 @@ pub extern "C" fn ibc_packet_ack( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -372,7 +373,7 @@ pub extern "C" fn ibc_packet_timeout( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -411,7 +412,7 @@ fn call_2_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { let r = match to_cache(cache) { @@ -452,7 +453,7 @@ fn do_call_2_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, ) -> Result, Error> { let gas_used = gas_used.ok_or_else(|| Error::empty_arg(GAS_USED_ARG))?; let checksum: Checksum = checksum @@ -470,7 +471,7 @@ fn do_call_2_args( let mut instance = cache.get_instance(&checksum, backend, options)?; // We only check this result after reporting gas usage and returning the instance into the cache. let res = vm_fn(&mut instance, arg1, arg2); - *gas_used = instance.create_gas_report().used_internally; + *gas_used = instance.create_gas_report().into(); instance.recycle(); Ok(res?) } @@ -497,7 +498,7 @@ fn call_3_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { let r = match to_cache(cache) { @@ -539,7 +540,7 @@ fn do_call_3_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut u64>, + gas_used: Option<&mut GasReport>, ) -> Result, Error> { let gas_used = gas_used.ok_or_else(|| Error::empty_arg(GAS_USED_ARG))?; let checksum: Checksum = checksum @@ -558,7 +559,7 @@ fn do_call_3_args( let mut instance = cache.get_instance(&checksum, backend, options)?; // We only check this result after reporting gas usage and returning the instance into the cache. let res = vm_fn(&mut instance, arg1, arg2, arg3); - *gas_used = instance.create_gas_report().used_internally; + *gas_used = instance.create_gas_report().into(); instance.recycle(); Ok(res?) } diff --git a/libwasmvm/src/gas_report.rs b/libwasmvm/src/gas_report.rs new file mode 100644 index 000000000..9a9c65dad --- /dev/null +++ b/libwasmvm/src/gas_report.rs @@ -0,0 +1,24 @@ +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct GasReport { + /// The original limit the instance was created with + pub limit: u64, + /// The remaining gas that can be spend + pub remaining: u64, + /// The amount of gas that was spend and metered externally in operations triggered by this instance + pub used_externally: u64, + /// The amount of gas that was spend and metered internally (i.e. by executing Wasm and calling + /// API methods which are not metered externally) + pub used_internally: u64, +} + +impl From for GasReport { + fn from(value: cosmwasm_vm::GasReport) -> Self { + Self { + limit: value.limit, + remaining: value.remaining, + used_externally: value.used_externally, + used_internally: value.used_internally, + } + } +} diff --git a/libwasmvm/src/lib.rs b/libwasmvm/src/lib.rs index 8cf1a0a17..2e431fe30 100644 --- a/libwasmvm/src/lib.rs +++ b/libwasmvm/src/lib.rs @@ -8,6 +8,7 @@ mod calls; mod db; mod error; mod gas_meter; +mod gas_report; mod iterator; mod memory; mod querier; @@ -23,6 +24,7 @@ pub use api::GoApi; pub use cache::{cache_t, load_wasm}; pub use db::{db_t, Db}; pub use error::GoError; +pub use gas_report::GasReport; pub use memory::{ destroy_unmanaged_vector, new_unmanaged_vector, ByteSliceView, U8SliceView, UnmanagedVector, }; From ea1c5c834d54466e663844d1dac739962e4b53e5 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 16 Aug 2023 13:08:25 +0200 Subject: [PATCH 2/6] Set libwasmvm version to 1.3.1 --- libwasmvm/Cargo.lock | 2 +- libwasmvm/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libwasmvm/Cargo.lock b/libwasmvm/Cargo.lock index 6b60b4c1c..772fb4364 100644 --- a/libwasmvm/Cargo.lock +++ b/libwasmvm/Cargo.lock @@ -1994,7 +1994,7 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wasmvm" -version = "1.3.0" +version = "1.3.1" dependencies = [ "cbindgen", "cosmwasm-std", diff --git a/libwasmvm/Cargo.toml b/libwasmvm/Cargo.toml index 83c1f4c7b..92f0a0eea 100644 --- a/libwasmvm/Cargo.toml +++ b/libwasmvm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmvm" -version = "1.3.0" +version = "1.3.1" publish = false authors = ["Ethan Frey "] edition = "2021" From b26795386815b79ae684a751b7b3f7db1409ac74 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Wed, 16 Aug 2023 15:56:55 +0200 Subject: [PATCH 3/6] Use destructuring for GasReport conversion --- libwasmvm/src/gas_report.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libwasmvm/src/gas_report.rs b/libwasmvm/src/gas_report.rs index 9a9c65dad..1f9e80ad6 100644 --- a/libwasmvm/src/gas_report.rs +++ b/libwasmvm/src/gas_report.rs @@ -13,12 +13,19 @@ pub struct GasReport { } impl From for GasReport { - fn from(value: cosmwasm_vm::GasReport) -> Self { + fn from( + cosmwasm_vm::GasReport { + limit, + remaining, + used_externally, + used_internally, + }: cosmwasm_vm::GasReport, + ) -> Self { Self { - limit: value.limit, - remaining: value.remaining, - used_externally: value.used_externally, - used_internally: value.used_internally, + limit, + remaining, + used_externally, + used_internally, } } } From 3e75d65f24979c411119d9dae1a09dc17e0a0b9a Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 17 Aug 2023 13:38:03 +0200 Subject: [PATCH 4/6] Adjust go side to new libwasmvm interface --- internal/api/bindings.h | 44 +++++++++++++------ internal/api/lib.go | 96 ++++++++++++++++++++--------------------- 2 files changed, 80 insertions(+), 60 deletions(-) diff --git a/internal/api/bindings.h b/internal/api/bindings.h index 60f301408..1f097dcec 100644 --- a/internal/api/bindings.h +++ b/internal/api/bindings.h @@ -342,6 +342,26 @@ typedef struct GoQuerier { struct Querier_vtable vtable; } GoQuerier; +typedef struct GasReport { + /** + * The original limit the instance was created with + */ + uint64_t limit; + /** + * The remaining gas that can be spend + */ + uint64_t remaining; + /** + * The amount of gas that was spend and metered externally in operations triggered by this instance + */ + uint64_t used_externally; + /** + * The amount of gas that was spend and metered internally (i.e. by executing Wasm and calling + * API methods which are not metered externally) + */ + uint64_t used_internally; +} GasReport; + struct cache_t *init_cache(struct ByteSliceView data_dir, struct ByteSliceView available_capabilities, uint32_t cache_size, @@ -391,7 +411,7 @@ struct UnmanagedVector instantiate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector execute(struct cache_t *cache, @@ -404,7 +424,7 @@ struct UnmanagedVector execute(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector migrate(struct cache_t *cache, @@ -416,7 +436,7 @@ struct UnmanagedVector migrate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector sudo(struct cache_t *cache, @@ -428,7 +448,7 @@ struct UnmanagedVector sudo(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector reply(struct cache_t *cache, @@ -440,7 +460,7 @@ struct UnmanagedVector reply(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector query(struct cache_t *cache, @@ -452,7 +472,7 @@ struct UnmanagedVector query(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_open(struct cache_t *cache, @@ -464,7 +484,7 @@ struct UnmanagedVector ibc_channel_open(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, @@ -476,7 +496,7 @@ struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_close(struct cache_t *cache, @@ -488,7 +508,7 @@ struct UnmanagedVector ibc_channel_close(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, @@ -500,7 +520,7 @@ struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, @@ -512,7 +532,7 @@ struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, @@ -524,7 +544,7 @@ struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - uint64_t *gas_used, + struct GasReport *gas_used, struct UnmanagedVector *error_msg); struct UnmanagedVector new_unmanaged_vector(bool nil, const uint8_t *ptr, uintptr_t length); diff --git a/internal/api/lib.go b/internal/api/lib.go index 4f4f07236..2fac44b82 100644 --- a/internal/api/lib.go +++ b/internal/api/lib.go @@ -189,15 +189,15 @@ func Instantiate( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.instantiate(cache.ptr, cs, e, i, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.instantiate(cache.ptr, cs, e, i, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func Execute( @@ -229,15 +229,15 @@ func Execute( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.execute(cache.ptr, cs, e, i, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.execute(cache.ptr, cs, e, i, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func Migrate( @@ -266,15 +266,15 @@ func Migrate( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.migrate(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.migrate(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func Sudo( @@ -303,15 +303,15 @@ func Sudo( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.sudo(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.sudo(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func Reply( @@ -340,15 +340,15 @@ func Reply( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.reply(cache.ptr, cs, e, r, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.reply(cache.ptr, cs, e, r, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func Query( @@ -377,15 +377,15 @@ func Query( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.query(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.query(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func IBCChannelOpen( @@ -414,15 +414,15 @@ func IBCChannelOpen( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.ibc_channel_open(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.ibc_channel_open(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func IBCChannelConnect( @@ -451,15 +451,15 @@ func IBCChannelConnect( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.ibc_channel_connect(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.ibc_channel_connect(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func IBCChannelClose( @@ -488,15 +488,15 @@ func IBCChannelClose( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.ibc_channel_close(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.ibc_channel_close(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func IBCPacketReceive( @@ -525,15 +525,15 @@ func IBCPacketReceive( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.ibc_packet_receive(cache.ptr, cs, e, pa, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.ibc_packet_receive(cache.ptr, cs, e, pa, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func IBCPacketAck( @@ -562,15 +562,15 @@ func IBCPacketAck( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.ibc_packet_ack(cache.ptr, cs, e, ac, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.ibc_packet_ack(cache.ptr, cs, e, ac, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } func IBCPacketTimeout( @@ -599,15 +599,15 @@ func IBCPacketTimeout( db := buildDB(&dbState, gasMeter) a := buildAPI(api) q := buildQuerier(querier) - var gasUsed cu64 + var gasReport C.GasReport errmsg := uninitializedUnmanagedVector() - res, err := C.ibc_packet_timeout(cache.ptr, cs, e, pa, db, a, q, cu64(gasLimit), cbool(printDebug), &gasUsed, &errmsg) + res, err := C.ibc_packet_timeout(cache.ptr, cs, e, pa, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasUsed), nil + return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } /**** To error module ***/ From f7a93aa66f8327e9c9bae7107c5a30255f2e8df2 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 21 Aug 2023 13:30:54 +0200 Subject: [PATCH 5/6] Rename gas_used to gas_report --- internal/api/bindings.h | 24 +++++++------- libwasmvm/bindings.h | 24 +++++++------- libwasmvm/src/args.rs | 2 +- libwasmvm/src/calls.rs | 70 ++++++++++++++++++++--------------------- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/internal/api/bindings.h b/internal/api/bindings.h index 1f097dcec..5b38b7736 100644 --- a/internal/api/bindings.h +++ b/internal/api/bindings.h @@ -411,7 +411,7 @@ struct UnmanagedVector instantiate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector execute(struct cache_t *cache, @@ -424,7 +424,7 @@ struct UnmanagedVector execute(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector migrate(struct cache_t *cache, @@ -436,7 +436,7 @@ struct UnmanagedVector migrate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector sudo(struct cache_t *cache, @@ -448,7 +448,7 @@ struct UnmanagedVector sudo(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector reply(struct cache_t *cache, @@ -460,7 +460,7 @@ struct UnmanagedVector reply(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector query(struct cache_t *cache, @@ -472,7 +472,7 @@ struct UnmanagedVector query(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_open(struct cache_t *cache, @@ -484,7 +484,7 @@ struct UnmanagedVector ibc_channel_open(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, @@ -496,7 +496,7 @@ struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_close(struct cache_t *cache, @@ -508,7 +508,7 @@ struct UnmanagedVector ibc_channel_close(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, @@ -520,7 +520,7 @@ struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, @@ -532,7 +532,7 @@ struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, @@ -544,7 +544,7 @@ struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector new_unmanaged_vector(bool nil, const uint8_t *ptr, uintptr_t length); diff --git a/libwasmvm/bindings.h b/libwasmvm/bindings.h index 1f097dcec..5b38b7736 100644 --- a/libwasmvm/bindings.h +++ b/libwasmvm/bindings.h @@ -411,7 +411,7 @@ struct UnmanagedVector instantiate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector execute(struct cache_t *cache, @@ -424,7 +424,7 @@ struct UnmanagedVector execute(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector migrate(struct cache_t *cache, @@ -436,7 +436,7 @@ struct UnmanagedVector migrate(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector sudo(struct cache_t *cache, @@ -448,7 +448,7 @@ struct UnmanagedVector sudo(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector reply(struct cache_t *cache, @@ -460,7 +460,7 @@ struct UnmanagedVector reply(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector query(struct cache_t *cache, @@ -472,7 +472,7 @@ struct UnmanagedVector query(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_open(struct cache_t *cache, @@ -484,7 +484,7 @@ struct UnmanagedVector ibc_channel_open(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, @@ -496,7 +496,7 @@ struct UnmanagedVector ibc_channel_connect(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_channel_close(struct cache_t *cache, @@ -508,7 +508,7 @@ struct UnmanagedVector ibc_channel_close(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, @@ -520,7 +520,7 @@ struct UnmanagedVector ibc_packet_receive(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, @@ -532,7 +532,7 @@ struct UnmanagedVector ibc_packet_ack(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, @@ -544,7 +544,7 @@ struct UnmanagedVector ibc_packet_timeout(struct cache_t *cache, struct GoQuerier querier, uint64_t gas_limit, bool print_debug, - struct GasReport *gas_used, + struct GasReport *gas_report, struct UnmanagedVector *error_msg); struct UnmanagedVector new_unmanaged_vector(bool nil, const uint8_t *ptr, uintptr_t length); diff --git a/libwasmvm/src/args.rs b/libwasmvm/src/args.rs index 69ab5fe72..cef0114f0 100644 --- a/libwasmvm/src/args.rs +++ b/libwasmvm/src/args.rs @@ -4,7 +4,7 @@ pub const AVAILABLE_CAPABILITIES_ARG: &str = "available_capabilities"; pub const CACHE_ARG: &str = "cache"; pub const WASM_ARG: &str = "wasm"; pub const CHECKSUM_ARG: &str = "checksum"; -pub const GAS_USED_ARG: &str = "gas_used"; +pub const GAS_REPORT_ARG: &str = "gas_report"; pub const ARG1: &str = "arg1"; pub const ARG2: &str = "arg2"; pub const ARG3: &str = "arg3"; diff --git a/libwasmvm/src/calls.rs b/libwasmvm/src/calls.rs index c0f7f7a6d..8d89a8788 100644 --- a/libwasmvm/src/calls.rs +++ b/libwasmvm/src/calls.rs @@ -11,7 +11,7 @@ use cosmwasm_vm::{ }; use crate::api::GoApi; -use crate::args::{ARG1, ARG2, ARG3, CACHE_ARG, CHECKSUM_ARG, GAS_USED_ARG}; +use crate::args::{ARG1, ARG2, ARG3, CACHE_ARG, CHECKSUM_ARG, GAS_REPORT_ARG}; use crate::cache::{cache_t, to_cache}; use crate::db::Db; use crate::error::{handle_c_error_binary, Error}; @@ -40,7 +40,7 @@ pub extern "C" fn instantiate( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_3_args( @@ -55,7 +55,7 @@ pub extern "C" fn instantiate( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -72,7 +72,7 @@ pub extern "C" fn execute( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_3_args( @@ -87,7 +87,7 @@ pub extern "C" fn execute( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -103,7 +103,7 @@ pub extern "C" fn migrate( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -117,7 +117,7 @@ pub extern "C" fn migrate( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -133,7 +133,7 @@ pub extern "C" fn sudo( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -147,7 +147,7 @@ pub extern "C" fn sudo( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -163,7 +163,7 @@ pub extern "C" fn reply( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -177,7 +177,7 @@ pub extern "C" fn reply( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -193,7 +193,7 @@ pub extern "C" fn query( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -207,7 +207,7 @@ pub extern "C" fn query( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -223,7 +223,7 @@ pub extern "C" fn ibc_channel_open( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -237,7 +237,7 @@ pub extern "C" fn ibc_channel_open( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -253,7 +253,7 @@ pub extern "C" fn ibc_channel_connect( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -267,7 +267,7 @@ pub extern "C" fn ibc_channel_connect( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -283,7 +283,7 @@ pub extern "C" fn ibc_channel_close( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -297,7 +297,7 @@ pub extern "C" fn ibc_channel_close( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -313,7 +313,7 @@ pub extern "C" fn ibc_packet_receive( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -327,7 +327,7 @@ pub extern "C" fn ibc_packet_receive( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -343,7 +343,7 @@ pub extern "C" fn ibc_packet_ack( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -357,7 +357,7 @@ pub extern "C" fn ibc_packet_ack( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -373,7 +373,7 @@ pub extern "C" fn ibc_packet_timeout( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { call_2_args( @@ -387,7 +387,7 @@ pub extern "C" fn ibc_packet_timeout( querier, gas_limit, print_debug, - gas_used, + gas_report, error_msg, ) } @@ -412,7 +412,7 @@ fn call_2_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { let r = match to_cache(cache) { @@ -428,7 +428,7 @@ fn call_2_args( querier, gas_limit, print_debug, - gas_used, + gas_report, ) })) .unwrap_or_else(|err| { @@ -453,9 +453,9 @@ fn do_call_2_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, ) -> Result, Error> { - let gas_used = gas_used.ok_or_else(|| Error::empty_arg(GAS_USED_ARG))?; + let gas_report = gas_report.ok_or_else(|| Error::empty_arg(GAS_REPORT_ARG))?; let checksum: Checksum = checksum .read() .ok_or_else(|| Error::unset_arg(CHECKSUM_ARG))? @@ -471,7 +471,7 @@ fn do_call_2_args( let mut instance = cache.get_instance(&checksum, backend, options)?; // We only check this result after reporting gas usage and returning the instance into the cache. let res = vm_fn(&mut instance, arg1, arg2); - *gas_used = instance.create_gas_report().into(); + *gas_report = instance.create_gas_report().into(); instance.recycle(); Ok(res?) } @@ -498,7 +498,7 @@ fn call_3_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, error_msg: Option<&mut UnmanagedVector>, ) -> UnmanagedVector { let r = match to_cache(cache) { @@ -515,7 +515,7 @@ fn call_3_args( querier, gas_limit, print_debug, - gas_used, + gas_report, ) })) .unwrap_or_else(|err| { @@ -540,9 +540,9 @@ fn do_call_3_args( querier: GoQuerier, gas_limit: u64, print_debug: bool, - gas_used: Option<&mut GasReport>, + gas_report: Option<&mut GasReport>, ) -> Result, Error> { - let gas_used = gas_used.ok_or_else(|| Error::empty_arg(GAS_USED_ARG))?; + let gas_report = gas_report.ok_or_else(|| Error::empty_arg(GAS_REPORT_ARG))?; let checksum: Checksum = checksum .read() .ok_or_else(|| Error::unset_arg(CHECKSUM_ARG))? @@ -559,7 +559,7 @@ fn do_call_3_args( let mut instance = cache.get_instance(&checksum, backend, options)?; // We only check this result after reporting gas usage and returning the instance into the cache. let res = vm_fn(&mut instance, arg1, arg2, arg3); - *gas_used = instance.create_gas_report().into(); + *gas_report = instance.create_gas_report().into(); instance.recycle(); Ok(res?) } From 996f97efed798acfc4a891ff8b76658319051d42 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 21 Aug 2023 13:39:38 +0200 Subject: [PATCH 6/6] Return full GasReport from internal api --- internal/api/lib.go | 81 ++++++++------ internal/api/lib_test.go | 32 +++--- lib.go | 230 +++++++++++++++------------------------ types/types.go | 16 +++ 4 files changed, 164 insertions(+), 195 deletions(-) diff --git a/internal/api/lib.go b/internal/api/lib.go index 2fac44b82..b73874307 100644 --- a/internal/api/lib.go +++ b/internal/api/lib.go @@ -172,7 +172,7 @@ func Instantiate( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -195,9 +195,9 @@ func Instantiate( res, err := C.instantiate(cache.ptr, cs, e, i, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func Execute( @@ -212,7 +212,7 @@ func Execute( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -235,9 +235,9 @@ func Execute( res, err := C.execute(cache.ptr, cs, e, i, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func Migrate( @@ -251,7 +251,7 @@ func Migrate( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -272,9 +272,9 @@ func Migrate( res, err := C.migrate(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func Sudo( @@ -288,7 +288,7 @@ func Sudo( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -309,9 +309,9 @@ func Sudo( res, err := C.sudo(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func Reply( @@ -325,7 +325,7 @@ func Reply( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -346,9 +346,9 @@ func Reply( res, err := C.reply(cache.ptr, cs, e, r, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func Query( @@ -362,7 +362,7 @@ func Query( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -383,9 +383,9 @@ func Query( res, err := C.query(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func IBCChannelOpen( @@ -399,7 +399,7 @@ func IBCChannelOpen( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -420,9 +420,9 @@ func IBCChannelOpen( res, err := C.ibc_channel_open(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func IBCChannelConnect( @@ -436,7 +436,7 @@ func IBCChannelConnect( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -457,9 +457,9 @@ func IBCChannelConnect( res, err := C.ibc_channel_connect(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func IBCChannelClose( @@ -473,7 +473,7 @@ func IBCChannelClose( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -494,9 +494,9 @@ func IBCChannelClose( res, err := C.ibc_channel_close(cache.ptr, cs, e, m, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func IBCPacketReceive( @@ -510,7 +510,7 @@ func IBCPacketReceive( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -531,9 +531,9 @@ func IBCPacketReceive( res, err := C.ibc_packet_receive(cache.ptr, cs, e, pa, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func IBCPacketAck( @@ -547,7 +547,7 @@ func IBCPacketAck( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -568,9 +568,9 @@ func IBCPacketAck( res, err := C.ibc_packet_ack(cache.ptr, cs, e, ac, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil } func IBCPacketTimeout( @@ -584,7 +584,7 @@ func IBCPacketTimeout( querier *Querier, gasLimit uint64, printDebug bool, -) ([]byte, uint64, error) { +) ([]byte, types.GasReport, error) { cs := makeView(checksum) defer runtime.KeepAlive(checksum) e := makeView(env) @@ -605,9 +605,18 @@ func IBCPacketTimeout( res, err := C.ibc_packet_timeout(cache.ptr, cs, e, pa, db, a, q, cu64(gasLimit), cbool(printDebug), &gasReport, &errmsg) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - return nil, uint64(gasReport.used_internally), errorWithMessage(err, errmsg) + return nil, convertGasReport(gasReport), errorWithMessage(err, errmsg) + } + return copyAndDestroyUnmanagedVector(res), convertGasReport(gasReport), nil +} + +func convertGasReport(report C.GasReport) types.GasReport { + return types.GasReport{ + Limit: uint64(report.limit), + Remaining: uint64(report.remaining), + UsedExternally: uint64(report.used_externally), + UsedInternally: uint64(report.used_internally), } - return copyAndDestroyUnmanagedVector(res), uint64(gasReport.used_internally), nil } /**** To error module ***/ diff --git a/internal/api/lib_test.go b/internal/api/lib_test.go index 9fd43e72b..e4d926f40 100644 --- a/internal/api/lib_test.go +++ b/internal/api/lib_test.go @@ -360,7 +360,7 @@ func TestInstantiate(t *testing.T) { res, cost, err := Instantiate(cache, checksum, env, info, msg, &igasMeter, store, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG) require.NoError(t, err) requireOkResponse(t, res, 0) - assert.Equal(t, uint64(0x13a78a36c), cost) + assert.Equal(t, uint64(0x13a78a36c), cost.UsedInternally) var result types.ContractResult err = json.Unmarshal(res, &result) @@ -391,8 +391,8 @@ func TestExecute(t *testing.T) { diff := time.Since(start) require.NoError(t, err) requireOkResponse(t, res, 0) - assert.Equal(t, uint64(0x13a78a36c), cost) - t.Logf("Time (%d gas): %s\n", cost, diff) + assert.Equal(t, uint64(0x13a78a36c), cost.UsedInternally) + t.Logf("Time (%d gas): %s\n", cost.UsedInternally, diff) // execute with the same store gasMeter2 := NewMockGasMeter(TESTING_GAS_LIMIT) @@ -404,8 +404,8 @@ func TestExecute(t *testing.T) { res, cost, err = Execute(cache, checksum, env, info, []byte(`{"release":{}}`), &igasMeter2, store, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG) diff = time.Since(start) require.NoError(t, err) - assert.Equal(t, uint64(0x222892d70), cost) - t.Logf("Time (%d gas): %s\n", cost, diff) + assert.Equal(t, uint64(0x222892d70), cost.UsedInternally) + t.Logf("Time (%d gas): %s\n", cost.UsedInternally, diff) // make sure it read the balance properly and we got 250 atoms var result types.ContractResult @@ -512,8 +512,8 @@ func TestExecuteCpuLoop(t *testing.T) { diff := time.Since(start) require.NoError(t, err) requireOkResponse(t, res, 0) - assert.Equal(t, uint64(0xd45091d0), cost) - t.Logf("Time (%d gas): %s\n", cost, diff) + assert.Equal(t, uint64(0xd45091d0), cost.UsedInternally) + t.Logf("Time (%d gas): %s\n", cost.UsedInternally, diff) // execute a cpu loop maxGas := uint64(40_000_000) @@ -525,8 +525,8 @@ func TestExecuteCpuLoop(t *testing.T) { _, cost, err = Execute(cache, checksum, env, info, []byte(`{"cpu_loop":{}}`), &igasMeter2, store, api, &querier, maxGas, TESTING_PRINT_DEBUG) diff = time.Since(start) require.Error(t, err) - assert.Equal(t, cost, maxGas) - t.Logf("CPULoop Time (%d gas): %s\n", cost, diff) + assert.Equal(t, cost.UsedInternally, maxGas) + t.Logf("CPULoop Time (%d gas): %s\n", cost.UsedInternally, diff) } func TestExecuteStorageLoop(t *testing.T) { @@ -557,15 +557,15 @@ func TestExecuteStorageLoop(t *testing.T) { store.SetGasMeter(gasMeter2) info = MockInfoBin(t, "fred") start := time.Now() - _, cost, err := Execute(cache, checksum, env, info, []byte(`{"storage_loop":{}}`), &igasMeter2, store, api, &querier, maxGas, TESTING_PRINT_DEBUG) + _, gasReport, err := Execute(cache, checksum, env, info, []byte(`{"storage_loop":{}}`), &igasMeter2, store, api, &querier, maxGas, TESTING_PRINT_DEBUG) diff := time.Since(start) require.Error(t, err) - t.Logf("StorageLoop Time (%d gas): %s\n", cost, diff) + t.Logf("StorageLoop Time (%d gas): %s\n", gasReport.UsedInternally, diff) t.Logf("Gas used: %d\n", gasMeter2.GasConsumed()) - t.Logf("Wasm gas: %d\n", cost) + t.Logf("Wasm gas: %d\n", gasReport.UsedInternally) // the "sdk gas" * GasMultiplier + the wasm cost should equal the maxGas (or be very close) - totalCost := cost + gasMeter2.GasConsumed() + totalCost := gasReport.UsedInternally + gasMeter2.GasConsumed() require.Equal(t, int64(maxGas), int64(totalCost)) } @@ -663,7 +663,7 @@ func TestMultipleInstances(t *testing.T) { require.NoError(t, err) requireOkResponse(t, res, 0) // we now count wasm gas charges and db writes - assert.Equal(t, uint64(0x138559c5c), cost) + assert.Equal(t, uint64(0x138559c5c), cost.UsedInternally) // instance2 controlled by mary gasMeter2 := NewMockGasMeter(TESTING_GAS_LIMIT) @@ -674,7 +674,7 @@ func TestMultipleInstances(t *testing.T) { res, cost, err = Instantiate(cache, checksum, env, info, msg, &igasMeter2, store2, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG) require.NoError(t, err) requireOkResponse(t, res, 0) - assert.Equal(t, uint64(0x1399177bc), cost) + assert.Equal(t, uint64(0x1399177bc), cost.UsedInternally) // fail to execute store1 with mary resp := exec(t, cache, checksum, "mary", store1, api, querier, 0x1218ff5d0) @@ -922,7 +922,7 @@ func exec(t *testing.T, cache Cache, checksum []byte, signer types.HumanAddress, info := MockInfoBin(t, signer) res, cost, err := Execute(cache, checksum, env, info, []byte(`{"release":{}}`), &igasMeter, store, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG) require.NoError(t, err) - assert.Equal(t, gasExpected, cost) + assert.Equal(t, gasExpected, cost.UsedInternally) var result types.ContractResult err = json.Unmarshal(res, &result) diff --git a/lib.go b/lib.go index 99f842fd8..99bd7c97b 100644 --- a/lib.go +++ b/lib.go @@ -136,26 +136,20 @@ func (vm *VM) Instantiate( if err != nil { return nil, 0, err } - data, gasUsed, err := api.Instantiate(vm.cache, checksum, envBin, infoBin, initMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.Instantiate(vm.cache, checksum, envBin, infoBin, initMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) - } - gasUsed += gasForDeserialization - var result types.ContractResult - err = json.Unmarshal(data, &result) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &result) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if result.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", result.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", result.Err) } - return result.Ok, gasUsed, nil + return result.Ok, gasReport.UsedInternally, nil } // Execute calls a given contract. Since the only difference between contracts with the same Checksum is the @@ -184,26 +178,20 @@ func (vm *VM) Execute( if err != nil { return nil, 0, err } - data, gasUsed, err := api.Execute(vm.cache, checksum, envBin, infoBin, executeMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.Execute(vm.cache, checksum, envBin, infoBin, executeMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err - } - - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + return nil, gasReport.UsedInternally, err } - gasUsed += gasForDeserialization var result types.ContractResult - err = json.Unmarshal(data, &result) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &result) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if result.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", result.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", result.Err) } - return result.Ok, gasUsed, nil + return result.Ok, gasReport.UsedInternally, nil } // Query allows a client to execute a contract-specific query. If the result is not empty, it should be @@ -224,26 +212,20 @@ func (vm *VM) Query( if err != nil { return nil, 0, err } - data, gasUsed, err := api.Query(vm.cache, checksum, envBin, queryMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.Query(vm.cache, checksum, envBin, queryMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) - } - gasUsed += gasForDeserialization - var resp types.QueryResponse - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // Migrate will migrate an existing contract to a new code binary. @@ -267,26 +249,20 @@ func (vm *VM) Migrate( if err != nil { return nil, 0, err } - data, gasUsed, err := api.Migrate(vm.cache, checksum, envBin, migrateMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.Migrate(vm.cache, checksum, envBin, migrateMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err - } - - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + return nil, gasReport.UsedInternally, err } - gasUsed += gasForDeserialization var resp types.ContractResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // Sudo allows native Go modules to make priviledged (sudo) calls on the contract. @@ -310,26 +286,20 @@ func (vm *VM) Sudo( if err != nil { return nil, 0, err } - data, gasUsed, err := api.Sudo(vm.cache, checksum, envBin, sudoMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.Sudo(vm.cache, checksum, envBin, sudoMsg, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err - } - - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + return nil, gasReport.UsedInternally, err } - gasUsed += gasForDeserialization var resp types.ContractResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // Reply allows the native Go wasm modules to make a priviledged call to return the result @@ -355,26 +325,20 @@ func (vm *VM) Reply( if err != nil { return nil, 0, err } - data, gasUsed, err := api.Reply(vm.cache, checksum, envBin, replyBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.Reply(vm.cache, checksum, envBin, replyBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) - } - gasUsed += gasForDeserialization - var resp types.ContractResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // IBCChannelOpen is available on IBC-enabled contracts and is a hook to call into @@ -398,26 +362,20 @@ func (vm *VM) IBCChannelOpen( if err != nil { return nil, 0, err } - data, gasUsed, err := api.IBCChannelOpen(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.IBCChannelOpen(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) - } - gasUsed += gasForDeserialization - var resp types.IBCChannelOpenResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // IBCChannelConnect is available on IBC-enabled contracts and is a hook to call into @@ -441,26 +399,20 @@ func (vm *VM) IBCChannelConnect( if err != nil { return nil, 0, err } - data, gasUsed, err := api.IBCChannelConnect(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.IBCChannelConnect(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err - } - - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + return nil, gasReport.UsedInternally, err } - gasUsed += gasForDeserialization var resp types.IBCBasicResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // IBCChannelClose is available on IBC-enabled contracts and is a hook to call into @@ -484,26 +436,20 @@ func (vm *VM) IBCChannelClose( if err != nil { return nil, 0, err } - data, gasUsed, err := api.IBCChannelClose(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.IBCChannelClose(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err - } - - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + return nil, gasReport.UsedInternally, err } - gasUsed += gasForDeserialization var resp types.IBCBasicResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // IBCPacketReceive is available on IBC-enabled contracts and is called when an incoming @@ -527,23 +473,17 @@ func (vm *VM) IBCPacketReceive( if err != nil { return nil, 0, err } - data, gasUsed, err := api.IBCPacketReceive(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.IBCPacketReceive(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) - } - gasUsed += gasForDeserialization - var resp types.IBCReceiveResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } - return &resp, gasUsed, nil + return &resp, gasReport.UsedInternally, nil } // IBCPacketAck is available on IBC-enabled contracts and is called when an @@ -568,26 +508,20 @@ func (vm *VM) IBCPacketAck( if err != nil { return nil, 0, err } - data, gasUsed, err := api.IBCPacketAck(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.IBCPacketAck(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err - } - - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + return nil, gasReport.UsedInternally, err } - gasUsed += gasForDeserialization var resp types.IBCBasicResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil } // IBCPacketTimeout is available on IBC-enabled contracts and is called when an @@ -612,24 +546,34 @@ func (vm *VM) IBCPacketTimeout( if err != nil { return nil, 0, err } - data, gasUsed, err := api.IBCPacketTimeout(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) + data, gasReport, err := api.IBCPacketTimeout(vm.cache, checksum, envBin, msgBin, &gasMeter, store, &goapi, &querier, gasLimit, vm.printDebug) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } - gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() - if gasLimit < gasForDeserialization+gasUsed { - return nil, gasUsed, fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) - } - gasUsed += gasForDeserialization - var resp types.IBCBasicResult - err = json.Unmarshal(data, &resp) + err = DeserializeResponse(gasLimit, deserCost, &gasReport, data, &resp) if err != nil { - return nil, gasUsed, err + return nil, gasReport.UsedInternally, err } if resp.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.Err) + return nil, gasReport.UsedInternally, fmt.Errorf("%s", resp.Err) } - return resp.Ok, gasUsed, nil + return resp.Ok, gasReport.UsedInternally, nil +} + +func DeserializeResponse(gasLimit uint64, deserCost types.UFraction, gasReport *types.GasReport, data []byte, response any) error { + gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() + if gasLimit < gasForDeserialization+gasReport.UsedInternally { + return fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + } + gasReport.UsedInternally += gasForDeserialization + gasReport.Remaining -= gasForDeserialization + + err := json.Unmarshal(data, response) + if err != nil { + return err + } + + return nil } diff --git a/types/types.go b/types/types.go index aa2cecdac..cfc3ed857 100644 --- a/types/types.go +++ b/types/types.go @@ -115,6 +115,22 @@ func (o OutOfGasError) Error() string { return "Out of gas" } +type GasReport struct { + Limit uint64 + Remaining uint64 + UsedExternally uint64 + UsedInternally uint64 +} + +func EmptyGasReport(limit uint64) GasReport { + return GasReport{ + Limit: limit, + Remaining: limit, + UsedExternally: 0, + UsedInternally: 0, + } +} + // Contains static analysis info of the contract (the Wasm code to be precise). // This type is returned by VM.AnalyzeCode(). type AnalysisReport struct {