Skip to content

Commit

Permalink
Fast PoI (#3678)
Browse files Browse the repository at this point in the history
* performance: Fast PoI impl; optimized heap access

* poi: move macro to stable-hash; more test coverage

* hygiene: replace asc_get_array with AscHeap::get_u32 to reduce unsafe

* performance: Move all usage of second-stack to WasmInstance field

* hygeine: add init_slice

* hygiene: rename AscHeap::init to AscHeap::read

* Bugfix: Remove UB from second-stack
  • Loading branch information
That3Percent authored Jul 14, 2022
1 parent 7f26f3c commit 9b6107d
Show file tree
Hide file tree
Showing 30 changed files with 732 additions and 875 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

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

25 changes: 15 additions & 10 deletions chain/near/src/trigger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ use graph::cheap_clone::CheapClone;
use graph::prelude::hex;
use graph::prelude::web3::types::H256;
use graph::prelude::BlockNumber;
use graph::runtime::asc_new;
use graph::runtime::gas::GasCounter;
use graph::runtime::AscHeap;
use graph::runtime::AscPtr;
use graph::runtime::DeterministicHostError;
use graph::runtime::{asc_new, gas::GasCounter, AscHeap, AscPtr, DeterministicHostError};
use std::{cmp::Ordering, sync::Arc};

use crate::codec;
Expand Down Expand Up @@ -155,6 +151,7 @@ mod tests {
data::subgraph::API_VERSION_0_0_5,
prelude::{hex, BigInt},
runtime::gas::GasCounter,
util::mem::init_slice,
};

#[test]
Expand Down Expand Up @@ -448,12 +445,18 @@ mod tests {
Ok((self.memory.len() - bytes.len()) as u32)
}

fn get(
fn read_u32(&self, offset: u32, gas: &GasCounter) -> Result<u32, DeterministicHostError> {
let mut data = [std::mem::MaybeUninit::<u8>::uninit(); 4];
let init = self.read(offset, &mut data, gas)?;
Ok(u32::from_le_bytes(init.try_into().unwrap()))
}

fn read<'a>(
&self,
offset: u32,
size: u32,
buffer: &'a mut [std::mem::MaybeUninit<u8>],
_gas: &GasCounter,
) -> Result<Vec<u8>, DeterministicHostError> {
) -> Result<&'a mut [u8], DeterministicHostError> {
let memory_byte_count = self.memory.len();
if memory_byte_count == 0 {
return Err(DeterministicHostError::from(anyhow!(
Expand All @@ -462,7 +465,7 @@ mod tests {
}

let start_offset = offset as usize;
let end_offset_exclusive = start_offset + size as usize;
let end_offset_exclusive = start_offset + buffer.len();

if start_offset >= memory_byte_count {
return Err(DeterministicHostError::from(anyhow!(
Expand All @@ -480,7 +483,9 @@ mod tests {
)));
}

return Ok(Vec::from(&self.memory[start_offset..end_offset_exclusive]));
let src = &self.memory[start_offset..end_offset_exclusive];

Ok(init_slice(src, buffer))
}

fn api_version(&self) -> graph::semver::Version {
Expand Down
9 changes: 8 additions & 1 deletion core/src/subgraph/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use graph::blockchain::block_stream::{BlockStreamEvent, BlockWithTriggers};
use graph::blockchain::{Block, Blockchain, DataSource, TriggerFilter as _};
use graph::components::{
store::ModificationsAndCache,
subgraph::{CausalityRegion, MappingError, ProofOfIndexing, SharedProofOfIndexing},
subgraph::{
CausalityRegion, MappingError, ProofOfIndexing, ProofOfIndexingVersion,
SharedProofOfIndexing,
},
};
use graph::data::store::scalar::Bytes;
use graph::data::subgraph::{
Expand Down Expand Up @@ -162,6 +165,10 @@ where
let proof_of_indexing = if self.inputs.store.supports_proof_of_indexing().await? {
Some(Arc::new(AtomicRefCell::new(ProofOfIndexing::new(
block_ptr.number,
// TODO: (Fast PoI) This should also support the Fast
// variant when indicated by the subgraph manifest.
// See also a0a79c0f-919f-4d97-a82 a-439a1ff78230
ProofOfIndexingVersion::Legacy,
))))
} else {
None
Expand Down
4 changes: 2 additions & 2 deletions graph/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ serde_derive = "1.0.125"
serde_json = { version = "1.0", features = ["arbitrary_precision"] }
serde_yaml = "0.8"
slog = { version = "2.7.0", features = ["release_max_level_trace", "max_level_trace"] }
stable-hash_legacy = { version = "0.3.2", package = "stable-hash" }
stable-hash = { version = "0.4.1"}
stable-hash_legacy = { version = "0.3.3", package = "stable-hash" }
stable-hash = { version = "0.4.2"}
strum = "0.21.0"
strum_macros = "0.21.1"
slog-async = "2.5.0"
Expand Down
28 changes: 4 additions & 24 deletions graph/src/blockchain/types.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use anyhow::anyhow;
use stable_hash::{FieldAddress, StableHash};
use stable_hash_legacy::SequenceNumber;
use std::convert::TryFrom;
use std::{fmt, str::FromStr};
use web3::types::{Block, H256};

use crate::data::graphql::IntoValue;
use crate::object;
use crate::prelude::{r, BigInt, TryFromValue, ValueMap};
use crate::util::stable_hash_glue::{impl_stable_hash, AsBytes};
use crate::{cheap_clone::CheapClone, components::store::BlockNumber};

/// A simple marker for byte arrays that are really block hashes
#[derive(Clone, Default, PartialEq, Eq, Hash)]
pub struct BlockHash(pub Box<[u8]>);

impl_stable_hash!(BlockHash(transparent: AsBytes));

impl BlockHash {
pub fn as_slice(&self) -> &[u8] {
&self.0
Expand Down Expand Up @@ -94,28 +95,7 @@ pub struct BlockPtr {

impl CheapClone for BlockPtr {}

impl stable_hash_legacy::StableHash for BlockPtr {
fn stable_hash<H: stable_hash_legacy::StableHasher>(
&self,
mut sequence_number: H::Seq,
state: &mut H,
) {
let BlockPtr { hash, number } = self;

stable_hash_legacy::utils::AsBytes(hash.0.as_ref())
.stable_hash(sequence_number.next_child(), state);
stable_hash_legacy::StableHash::stable_hash(number, sequence_number.next_child(), state);
}
}

impl StableHash for BlockPtr {
fn stable_hash<H: stable_hash::StableHasher>(&self, field_address: H::Addr, state: &mut H) {
let BlockPtr { hash, number } = self;

stable_hash::utils::AsBytes(hash.0.as_ref()).stable_hash(field_address.child(0), state);
stable_hash::StableHash::stable_hash(number, field_address.child(1), state);
}
}
impl_stable_hash!(BlockPtr { hash, number });

impl BlockPtr {
pub fn new(hash: BlockHash, number: BlockNumber) -> Self {
Expand Down
48 changes: 6 additions & 42 deletions graph/src/components/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ mod traits;
pub use cache::{CachedEthereumCall, EntityCache, ModificationsAndCache};
pub use err::StoreError;
use itertools::Itertools;
use stable_hash::{FieldAddress, StableHash};
use stable_hash_legacy::SequenceNumber;
pub use traits::*;

use futures::stream::poll_fn;
Expand All @@ -26,6 +24,7 @@ use crate::blockchain::{Block, Blockchain};
use crate::data::store::scalar::Bytes;
use crate::data::store::*;
use crate::prelude::*;
use crate::util::stable_hash_glue::impl_stable_hash;

/// The type name of an entity. This is the string that is used in the
/// subgraph's GraphQL schema as `type NAME @entity { .. }`
Expand Down Expand Up @@ -110,46 +109,11 @@ pub struct EntityKey {
pub entity_id: String,
}

impl stable_hash_legacy::StableHash for EntityKey {
fn stable_hash<H: stable_hash_legacy::StableHasher>(
&self,
mut sequence_number: H::Seq,
state: &mut H,
) {
let Self {
subgraph_id,
entity_type,
entity_id,
} = self;

stable_hash_legacy::StableHash::stable_hash(
subgraph_id,
sequence_number.next_child(),
state,
);
stable_hash_legacy::StableHash::stable_hash(
&entity_type.as_str(),
sequence_number.next_child(),
state,
);
stable_hash_legacy::StableHash::stable_hash(entity_id, sequence_number.next_child(), state);
}
}

impl StableHash for EntityKey {
fn stable_hash<H: stable_hash::StableHasher>(&self, field_address: H::Addr, state: &mut H) {
let Self {
subgraph_id,
entity_type,
entity_id,
} = self;

subgraph_id.stable_hash(field_address.child(0), state);

stable_hash::StableHash::stable_hash(&entity_type.as_str(), field_address.child(1), state);
stable_hash::StableHash::stable_hash(entity_id, field_address.child(2), state);
}
}
impl_stable_hash!(EntityKey {
subgraph_id,
entity_type: EntityType::as_str,
entity_id
});

impl EntityKey {
pub fn data(subgraph_id: DeploymentHash, entity_type: String, entity_id: String) -> Self {
Expand Down
4 changes: 2 additions & 2 deletions graph/src/components/subgraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub use self::host::{HostMetrics, MappingError, RuntimeHost, RuntimeHostBuilder}
pub use self::instance::{BlockState, DataSourceTemplateInfo};
pub use self::instance_manager::SubgraphInstanceManager;
pub use self::proof_of_indexing::{
BlockEventStream, CausalityRegion, ProofOfIndexing, ProofOfIndexingEvent,
ProofOfIndexingFinisher, SharedProofOfIndexing,
CausalityRegion, ProofOfIndexing, ProofOfIndexingEvent, ProofOfIndexingFinisher,
ProofOfIndexingVersion, SharedProofOfIndexing,
};
pub use self::provider::SubgraphAssignmentProvider;
pub use self::registrar::{SubgraphRegistrar, SubgraphVersionSwitchingMode};
Loading

0 comments on commit 9b6107d

Please sign in to comment.