forked from near/nearcore
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
runtime: implement a receipt preparation pipeline (near#11839)
This PR implements a very basic form of pipelining of the contract preparation. In particular with this PR only actions from one upcoming "interesting" local receipt is handled, with other receipt kinds (incoming, delayed) being left for a future change. I don't anticipate any trouble integrating them as they largely have similar data and structure as the local receipts seen here. The primary reason I want this reviewed separately, however, is due to the changes to storage. You will notice that I have largely changed the code to read contracts without going through The State (i.e. it now reads the contract code directly via the code hash.) However at the same time writing of the contract continues involving The State; largely because I don't want to deal with migrations and similar such complexities… but also because `TrieStorage` does not provide write access. This also means that writing is transactional and I had to add some work-arounds to the `store::contract::Storage` in order to make deployed contracts visible before the commit.
- Loading branch information
Showing
9 changed files
with
545 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use crate::TrieStorage; | ||
use near_primitives::hash::CryptoHash; | ||
use near_vm_runner::ContractCode; | ||
use std::collections::BTreeMap; | ||
use std::sync::{Arc, Mutex}; | ||
|
||
/// Reads contract code from the trie by its hash. | ||
/// | ||
/// Cloning is cheap. | ||
#[derive(Clone)] | ||
pub struct ContractStorage { | ||
storage: Arc<dyn TrieStorage>, | ||
|
||
/// During an apply of a single chunk contracts may be deployed through the | ||
/// `Action::DeployContract`. | ||
/// | ||
/// Unfortunately `TrieStorage` does not have a way to write to the underlying storage, and the | ||
/// `TrieUpdate` will only write the contract once the whole transaction is committed at the | ||
/// end of the chunk's apply. | ||
/// | ||
/// As a temporary work-around while we're still involving `Trie` for `ContractCode` storage, | ||
/// we'll keep a list of such deployed contracts here. Once the contracts are no longer part of | ||
/// The State this field should be removed, and the `Storage::store` function should be | ||
/// adjusted to write out the contract into the relevant part of the database immediately | ||
/// (without going through transactional storage operations and such). | ||
uncommitted_deploys: Arc<Mutex<BTreeMap<CryptoHash, ContractCode>>>, | ||
} | ||
|
||
impl ContractStorage { | ||
pub fn new(storage: Arc<dyn TrieStorage>) -> Self { | ||
Self { storage, uncommitted_deploys: Default::default() } | ||
} | ||
|
||
pub fn get(&self, code_hash: CryptoHash) -> Option<ContractCode> { | ||
{ | ||
let guard = self.uncommitted_deploys.lock().expect("no panics"); | ||
if let Some(v) = guard.get(&code_hash) { | ||
return Some(ContractCode::new(v.code().to_vec(), Some(code_hash))); | ||
} | ||
} | ||
|
||
match self.storage.retrieve_raw_bytes(&code_hash) { | ||
Ok(raw_code) => Some(ContractCode::new(raw_code.to_vec(), Some(code_hash))), | ||
Err(_) => None, | ||
} | ||
} | ||
|
||
pub fn store(&self, code: ContractCode) { | ||
let mut guard = self.uncommitted_deploys.lock().expect("no panics"); | ||
guard.insert(*code.hash(), code); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.