Skip to content

runtime: Use interior mutability in AscHeapCtx #6053

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
9 changes: 4 additions & 5 deletions chain/ethereum/src/runtime/runtime_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use graph::blockchain::ChainIdentifier;
use graph::components::subgraph::HostMetrics;
use graph::data::store::ethereum::call;
use graph::data::store::scalar::BigInt;
use graph::data::subgraph::API_VERSION_0_0_9;
use graph::data::subgraph::{API_VERSION_0_0_4, API_VERSION_0_0_9};
use graph::data_source;
use graph::data_source::common::{ContractCall, MappingABI};
use graph::prelude::web3::types::H160;
Expand All @@ -26,7 +26,6 @@ use graph::{
EthereumCallCache,
},
runtime::{asc_get, asc_new, AscPtr, HostExportError},
semver::Version,
slog::Logger,
};
use graph_runtime_wasm::asc_abi::class::{AscBigInt, AscEnumArray, AscWrapped, EthereumValueKind};
Expand Down Expand Up @@ -185,7 +184,7 @@ fn ethereum_call(
// For apiVersion >= 0.0.4 the call passed from the mapping includes the
// function signature; subgraphs using an apiVersion < 0.0.4 don't pass
// the signature along with the call.
let call: UnresolvedContractCall = if ctx.heap.api_version() >= Version::new(0, 0, 4) {
let call: UnresolvedContractCall = if ctx.heap.api_version() >= &API_VERSION_0_0_4 {
asc_get::<_, AscUnresolvedContractCall_0_0_4, _>(ctx.heap, wasm_ptr.into(), &ctx.gas, 0)?
} else {
asc_get::<_, AscUnresolvedContractCall, _>(ctx.heap, wasm_ptr.into(), &ctx.gas, 0)?
Expand Down Expand Up @@ -215,7 +214,7 @@ fn eth_get_balance(
ctx.gas
.consume_host_fn_with_metrics(ETH_GET_BALANCE, "eth_get_balance")?;

if ctx.heap.api_version() < API_VERSION_0_0_9 {
if ctx.heap.api_version() < &API_VERSION_0_0_9 {
return Err(HostExportError::Deterministic(anyhow!(
"ethereum.getBalance call is not supported before API version 0.0.9"
)));
Expand Down Expand Up @@ -249,7 +248,7 @@ fn eth_has_code(
ctx.gas
.consume_host_fn_with_metrics(ETH_HAS_CODE, "eth_has_code")?;

if ctx.heap.api_version() < API_VERSION_0_0_9 {
if ctx.heap.api_version() < &API_VERSION_0_0_9 {
return Err(HostExportError::Deterministic(anyhow!(
"ethereum.hasCode call is not supported before API version 0.0.9"
)));
Expand Down
12 changes: 6 additions & 6 deletions chain/ethereum/src/trigger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl ToAscPtr for MappingTrigger {
log.as_ref(),
&params,
);
if api_version >= API_VERSION_0_0_7 {
if api_version >= &API_VERSION_0_0_7 {
asc_new::<
AscEthereumEvent_0_0_7<
AscEthereumTransaction_0_0_6,
Expand All @@ -161,14 +161,14 @@ impl ToAscPtr for MappingTrigger {
_,
>(heap, &(ethereum_event_data, receipt.as_deref()), gas)?
.erase()
} else if api_version >= API_VERSION_0_0_6 {
} else if api_version >= &API_VERSION_0_0_6 {
asc_new::<
AscEthereumEvent<AscEthereumTransaction_0_0_6, AscEthereumBlock_0_0_6>,
_,
_,
>(heap, &ethereum_event_data, gas)?
.erase()
} else if api_version >= API_VERSION_0_0_2 {
} else if api_version >= &API_VERSION_0_0_2 {
asc_new::<
AscEthereumEvent<AscEthereumTransaction_0_0_2, AscEthereumBlock>,
_,
Expand All @@ -192,14 +192,14 @@ impl ToAscPtr for MappingTrigger {
outputs,
} => {
let call = EthereumCallData::new(&block, &transaction, &call, &inputs, &outputs);
if heap.api_version() >= Version::new(0, 0, 6) {
if heap.api_version() >= &Version::new(0, 0, 6) {
asc_new::<
AscEthereumCall_0_0_3<AscEthereumTransaction_0_0_6, AscEthereumBlock_0_0_6>,
_,
_,
>(heap, &call, gas)?
.erase()
} else if heap.api_version() >= Version::new(0, 0, 3) {
} else if heap.api_version() >= &Version::new(0, 0, 3) {
asc_new::<
AscEthereumCall_0_0_3<AscEthereumTransaction_0_0_2, AscEthereumBlock>,
_,
Expand All @@ -212,7 +212,7 @@ impl ToAscPtr for MappingTrigger {
}
MappingTrigger::Block { block } => {
let block = EthereumBlockData::from(block.as_ref());
if heap.api_version() >= Version::new(0, 0, 6) {
if heap.api_version() >= &Version::new(0, 0, 6) {
asc_new::<AscEthereumBlock_0_0_6, _, _>(heap, &block, gas)?.erase()
} else {
asc_new::<AscEthereumBlock, _, _>(heap, &block, gas)?.erase()
Expand Down
4 changes: 2 additions & 2 deletions chain/near/src/trigger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,8 @@ mod tests {
Ok(init_slice(src, buffer))
}

fn api_version(&self) -> graph::semver::Version {
self.api_version.clone()
fn api_version(&self) -> &graph::semver::Version {
&self.api_version
}

fn asc_type_id(
Expand Down
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 @@ -5,6 +5,9 @@ use thiserror::Error;

pub const API_VERSION_0_0_2: Version = Version::new(0, 0, 2);

/// Changed calling convention for `ethereum.call`
pub const API_VERSION_0_0_4: Version = Version::new(0, 0, 4);

/// This version adds a new subgraph validation step that rejects manifests whose mappings have
/// different API versions if at least one of them is equal to or higher than `0.0.5`.
pub const API_VERSION_0_0_5: Version = Version::new(0, 0, 5);
Expand Down
2 changes: 1 addition & 1 deletion graph/src/runtime/asc_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub trait AscHeap {

fn read_u32(&self, offset: u32, gas: &GasCounter) -> Result<u32, DeterministicHostError>;

fn api_version(&self) -> Version;
fn api_version(&self) -> &Version;

fn asc_type_id(&mut self, type_id_index: IndexForAscTypeId) -> Result<u32, HostExportError>;
}
Expand Down
6 changes: 4 additions & 2 deletions graph/src/runtime/asc_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::data::subgraph::API_VERSION_0_0_4;

use super::gas::GasCounter;
use super::{padding_to_16, DeterministicHostError, HostExportError};

Expand Down Expand Up @@ -61,7 +63,7 @@ impl<C: AscType> AscPtr<C> {
let len = match heap.api_version() {
// TODO: The version check here conflicts with the comment on C::asc_size,
// which states "Only used for version <= 0.0.3."
version if version <= Version::new(0, 0, 4) => C::asc_size(self, heap, gas),
version if version <= &API_VERSION_0_0_4 => C::asc_size(self, heap, gas),
_ => self.read_len(heap, gas),
}?;

Expand Down Expand Up @@ -91,7 +93,7 @@ impl<C: AscType> AscPtr<C> {
C: AscIndexId,
{
match heap.api_version() {
version if version <= Version::new(0, 0, 4) => {
version if version <= &API_VERSION_0_0_4 => {
let heap_ptr = heap.raw_new(&asc_obj.to_asc_bytes()?, gas)?;
Ok(AscPtr::new(heap_ptr))
}
Expand Down
17 changes: 10 additions & 7 deletions runtime/wasm/src/asc_abi/class.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use ethabi;

use graph::{
data::store::{self, scalar::Timestamp},
data::{
store::{self, scalar::Timestamp},
subgraph::API_VERSION_0_0_4,
},
runtime::{
gas::GasCounter, AscHeap, AscIndexId, AscType, AscValue, HostExportError,
IndexForAscTypeId, ToAscObj,
Expand All @@ -27,10 +30,10 @@ pub enum ArrayBuffer {
impl ArrayBuffer {
pub(crate) fn new<T: AscType>(
values: &[T],
api_version: Version,
api_version: &Version,
) -> Result<Self, DeterministicHostError> {
match api_version {
version if version <= Version::new(0, 0, 4) => {
version if version <= &API_VERSION_0_0_4 => {
Ok(Self::ApiVersion0_0_4(v0_0_4::ArrayBuffer::new(values)?))
}
_ => Ok(Self::ApiVersion0_0_5(v0_0_5::ArrayBuffer::new(values)?)),
Expand Down Expand Up @@ -95,7 +98,7 @@ impl<T: AscValue> TypedArray<T> {
gas: &GasCounter,
) -> Result<Self, HostExportError> {
match heap.api_version() {
version if version <= Version::new(0, 0, 4) => Ok(Self::ApiVersion0_0_4(
version if version <= &API_VERSION_0_0_4 => Ok(Self::ApiVersion0_0_4(
v0_0_4::TypedArray::new(content, heap, gas)?,
)),
_ => Ok(Self::ApiVersion0_0_5(v0_0_5::TypedArray::new(
Expand Down Expand Up @@ -201,9 +204,9 @@ pub enum AscString {
}

impl AscString {
pub fn new(content: &[u16], api_version: Version) -> Result<Self, DeterministicHostError> {
pub fn new(content: &[u16], api_version: &Version) -> Result<Self, DeterministicHostError> {
match api_version {
version if version <= Version::new(0, 0, 4) => {
version if version <= &API_VERSION_0_0_4 => {
Ok(Self::ApiVersion0_0_4(v0_0_4::AscString::new(content)?))
}
_ => Ok(Self::ApiVersion0_0_5(v0_0_5::AscString::new(content)?)),
Expand Down Expand Up @@ -275,7 +278,7 @@ impl<T: AscValue> Array<T> {
gas: &GasCounter,
) -> Result<Self, HostExportError> {
match heap.api_version() {
version if version <= Version::new(0, 0, 4) => Ok(Self::ApiVersion0_0_4(
version if version <= &API_VERSION_0_0_4 => Ok(Self::ApiVersion0_0_4(
v0_0_4::Array::new(content, heap, gas)?,
)),
_ => Ok(Self::ApiVersion0_0_5(v0_0_5::Array::new(
Expand Down
2 changes: 1 addition & 1 deletion runtime/wasm/src/asc_abi/v0_0_4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl ArrayBuffer {
&self,
byte_offset: u32,
length: u32,
api_version: Version,
api_version: &Version,
) -> Result<Vec<T>, DeterministicHostError> {
let length = length as usize;
let byte_offset = byte_offset as usize;
Expand Down
4 changes: 2 additions & 2 deletions runtime/wasm/src/asc_abi/v0_0_5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ impl ArrayBuffer {
&self,
byte_offset: u32,
length: u32,
api_version: Version,
api_version: &Version,
) -> Result<Vec<T>, DeterministicHostError> {
let length = length as usize;
let byte_offset = byte_offset as usize;

self.content[byte_offset..]
.chunks(size_of::<T>())
.take(length)
.map(|asc_obj| T::from_asc_bytes(asc_obj, &api_version))
.map(|asc_obj| T::from_asc_bytes(asc_obj, api_version))
.collect()
}
}
Expand Down
19 changes: 6 additions & 13 deletions runtime/wasm/src/module/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@ impl WasmInstanceContext<'_> {
self.inner.data_mut()
}

pub fn asc_heap_ref(&self) -> &AscHeapCtx {
self.as_ref().asc_heap_ref()
}

pub fn asc_heap_mut(&mut self) -> &mut AscHeapCtx {
self.as_mut().asc_heap_mut()
pub fn asc_heap(&self) -> &Arc<AscHeapCtx> {
self.as_ref().asc_heap()
}

pub fn suspend_timeout(&mut self) {
Expand Down Expand Up @@ -96,7 +92,7 @@ pub struct WasmInstanceData {

// This option is needed to break the cyclic dependency between, instance, store, and context.
// during execution it should always be populated.
asc_heap: Option<AscHeapCtx>,
asc_heap: Option<Arc<AscHeapCtx>>,
}

impl WasmInstanceData {
Expand All @@ -117,15 +113,12 @@ impl WasmInstanceData {
}
}

pub fn set_asc_heap(&mut self, asc_heap: AscHeapCtx) {
pub fn set_asc_heap(&mut self, asc_heap: Arc<AscHeapCtx>) {
self.asc_heap = Some(asc_heap);
}

pub fn asc_heap_ref(&self) -> &AscHeapCtx {
self.asc_heap.as_ref().unwrap()
}
pub fn asc_heap_mut(&mut self) -> &mut AscHeapCtx {
self.asc_heap.as_mut().unwrap()
pub fn asc_heap(&self) -> &Arc<AscHeapCtx> {
self.asc_heap.as_ref().expect("asc_heap not set")
}

pub fn take_state(mut self) -> BlockState {
Expand Down
Loading