Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions graph/src/data/subgraph/api_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub const API_VERSION_0_0_8: Version = Version::new(0, 0, 8);
/// Enables new host function `eth_get_balance`
pub const API_VERSION_0_0_9: Version = Version::new(0, 0, 9);

/// Enables new host function `ethereum.decodeParams`
pub const API_VERSION_0_0_10: Version = Version::new(0, 0, 10);

/// Before this check was introduced, there were already subgraphs in the wild with spec version
/// 0.0.3, due to confusion with the api version. To avoid breaking those, we accept 0.0.3 though it
/// doesn't exist.
Expand Down
2 changes: 1 addition & 1 deletion graph/src/env/mappings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub struct InnerMappingHandlers {
entity_cache_dead_weight: EnvVarBoolean,
#[envconfig(from = "GRAPH_ENTITY_CACHE_SIZE", default = "10000")]
entity_cache_size_in_kb: usize,
#[envconfig(from = "GRAPH_MAX_API_VERSION", default = "0.0.9")]
#[envconfig(from = "GRAPH_MAX_API_VERSION", default = "0.0.10")]
max_api_version: Version,
#[envconfig(from = "GRAPH_MAPPING_HANDLER_TIMEOUT")]
mapping_handler_timeout_in_secs: Option<u64>,
Expand Down
24 changes: 24 additions & 0 deletions runtime/wasm/src/host_exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,30 @@ impl HostExports {
ty.abi_decode(&data).context("Failed to decode")
}

/// Like [`Self::ethereum_decode`], but decodes `data` as ABI function
/// parameters (the layout used by transaction calldata and event data)
/// rather than as a single ABI value. The two differ only for a top-level
/// tuple with at least one dynamic field: calldata has no leading offset
/// word, which `abi_decode` would otherwise expect.
pub(crate) fn ethereum_decode_params(
&self,
types: String,
data: Vec<u8>,
gas: &GasCounter,
state: &mut BlockState,
) -> Result<abi::DynSolValue, anyhow::Error> {
Self::track_gas_and_ops(
gas,
state,
gas::DEFAULT_GAS_OP.with_args(complexity::Size, &data),
"ethereum_decode_params",
)?;

let ty: abi::DynSolType = types.parse().context("Failed to read types")?;

ty.abi_decode_params(&data).context("Failed to decode")
}

pub(crate) fn yaml_from_bytes(
&self,
bytes: &[u8],
Expand Down
20 changes: 20 additions & 0 deletions runtime/wasm/src/module/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,26 @@ impl WasmInstanceContext<'_> {
}
}

/// function decodeParams(types: String, data: Bytes): ethereum.Value | null
pub async fn ethereum_decode_params(
&mut self,
gas: &GasCounter,
types_ptr: AscPtr<AscString>,
data_ptr: AscPtr<Uint8Array>,
) -> Result<AscPtr<AscEnum<EthereumValueKind>>, HostExportError> {
let types = asc_get(self, types_ptr, gas)?;
let data = asc_get(self, data_ptr, gas)?;
let host_exports = self.as_ref().ctx.host_exports.cheap_clone();
let ctx = &mut self.as_mut().ctx;
let result = host_exports.ethereum_decode_params(types, data, gas, &mut ctx.state);

// return `null` if it fails
match result {
Ok(token) => asc_new(self, &token, gas).await,
Err(_) => Ok(AscPtr::null()),
}
}

/// function arweave.transactionData(txId: string): Bytes | null
pub async fn arweave_transaction_data(
&self,
Expand Down
6 changes: 6 additions & 0 deletions runtime/wasm/src/module/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,12 @@ pub(crate) fn build_linker(

link!("ethereum.encode", ethereum_encode, params_ptr);
link!("ethereum.decode", ethereum_decode, params_ptr, data_ptr);
link!(
"ethereum.decodeParams",
ethereum_decode_params,
params_ptr,
data_ptr
);

link!("abort", abort, message_ptr, file_name_ptr, line, column);

Expand Down
Loading