Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

BREAKING Overlay transaction support. #3263

Closed
wants to merge 203 commits into from

Conversation

cheme
Copy link
Contributor

@cheme cheme commented Jul 30, 2019

BREAKING: this pr adds externalities, and change mutability of existing one, the corresponding

This PR is a refactor of overlay_change to allow transactional support, it is similar to paritytech/polkadot-sdk#370 goals, but does not stack Ext, it only stacks storage.

It also switches from a stack of hashmap (previously prospective and top) to a single hashmap (containing history of values) and a transaction global state. Those values with state are managed
with 'historied-data' crate (simple vec of data to query in front of a reference global state).

Under this design access to data is not badly impacted by the number of open transactional layers.
I did fuzz this code a bit against a partial simple layered hashmap implementation.

Usage from a runtime with a function, in a similar way as ext_try from paritytech/polkadot-sdk#370, there is the very simple with_transaction function: internally it uses three host functions ext_start_transaction, ext_commit_transaction and ext_discard_transaction. This does not look as good as the single ext_try but is clearer: memory mgmt seems way simplier (as there is none).

Note that to call global state action, modification of local values need to be synchronize.
eg discard_transaction on states must be follow by apply_discard_transaction for all values related to this state and then follow by ensure_running.

Technically we only maintain a counter of current number of stacked transaction as a global state (this start at 1 and can be 0 only to update some values: case of discarding content, but will then return to 1 through 'finalize_discard' call).
Local state is either committed or the number of stacked transaction when the value was changed, this state is stored with the value history.

polkadot companion: paritytech/polkadot#999

@cheme cheme added the A3-in_progress Pull request is in progress. No review needed at this stage. label Jul 30, 2019
Copy link
Contributor

@pepyakin pepyakin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a half way through to #2980! (With another part being an runtime instance state/linear memory concerns). But even with that, I think it might be super useful!

We even might be able to construct ext_try from primitives introduced in this PR and with a future introduced primitives for cloning a wasm instance!

core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/sr-io/without_std.rs Outdated Show resolved Hide resolved
core/sr-io/without_std.rs Outdated Show resolved Hide resolved
core/state-machine/src/basic.rs Outdated Show resolved Hide resolved
core/state-machine/src/ext.rs Outdated Show resolved Hide resolved
core/state-machine/Cargo.toml Outdated Show resolved Hide resolved
srml/support/src/storage/mod.rs Outdated Show resolved Hide resolved
srml/support/src/storage/mod.rs Outdated Show resolved Hide resolved
core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/executor/src/wasm_executor.rs Outdated Show resolved Hide resolved
core/state-machine/Cargo.toml Outdated Show resolved Hide resolved
@gui1117
Copy link
Contributor

gui1117 commented Jul 31, 2019

Currently transactional primitives methods name can be a bit confusing (start_transaction do open an new transactional layer but next to this method there is also submit_transaction that submit an actual chain transaction).
So another name than 'transaction' should be suitable.

Maybe start_transactional_layer

@cheme
Copy link
Contributor Author

cheme commented Jul 31, 2019

Maybe start_transactional_layer

I forgot to update my comment, I change it to 'storage_start_transaction' but maybe 'start_transactional_layer' is better?

@pepyakin
Copy link
Contributor

pepyakin commented Jul 31, 2019

I am actually not sure about the wording "layer". I.e. transactional layer of what? What if we get another kind of layer? On the other hand, "storage transaction" is unambigious.

core/state-machine/src/changes_trie/build.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
core/state-machine/src/overlayed_changes.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@pepyakin pepyakin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First brief look.

@@ -313,6 +313,25 @@ pub trait Storage {
}
}

/// Interface for managing transaction within the runtime.
#[runtime_interface]
pub trait Transaction {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if StorageTransactions will be a better name?

// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

//! Types and method for managing a stack of transactional values.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//! Types and method for managing a stack of transactional values.
//! Types and methods for managing a stack of transactional values.

(_, Some(overlay_key)) => if overlay_key.1.value.is_some() {
return Some(overlay_key.0.to_vec())
} else {
// TODO make this function non recursive to avoid this clone
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this TODO need to be fixed before landing this? If not, an issue is required.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No those TODO were just a note to myself, I am removing them.

};
// TODO no need to query child at each recursive iter here
// and also find a way to remove the clone (non recursive and global mut handle should do the
// trick).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this TODO need to be fixed before landing this? If not, an issue is required.

@@ -136,8 +136,7 @@ where

self.backend.pairs().iter()
.map(|&(ref k, ref v)| (k.to_vec(), Some(v.to_vec())))
.chain(self.overlay.committed.top.clone().into_iter().map(|(k, v)| (k, v.value)))
.chain(self.overlay.prospective.top.clone().into_iter().map(|(k, v)| (k, v.value)))
.chain(self.overlay.changes.iter_values(None).map(|(k, v)| (k.to_vec(), v.map(|s| s.to_vec()))))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line exceeds the recommended limit for 100 characters. Can we wrap this line?

TxPending,
/// The transaction has been discarded.
/// Data from a `LayerEntry` pointing to this layer state should
/// not be returned and can be remove.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: can be removed

/// Get latest prospective value, excludes
/// committed values.
pub(crate) fn get_prospective(&self, states: &States) -> Option<&V> {
let self_len = self.len();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it a bit confusing that the definition of len is in another module. Can we move these definitions closer together?

/// triggering.
///
/// With this default values it should be very unlikelly that gc is needed
/// during a block processing for most use case.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: use cases

// This information is redundant as it could be
// calculated by iterating backward over `history`
// field.
// Managing this cache allow use to have
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: us?

None
}

/// Push a value without checking without transactional layer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: redundant without?

@pepyakin pepyakin dismissed their stale review January 30, 2020 15:01

Significant change of the implementation after my look.

@cheme cheme requested a review from NikVolf as a code owner April 14, 2020 15:42
@cheme
Copy link
Contributor Author

cheme commented May 14, 2020

This is stale, closing it, @athei will be working on the subject, keeping it open will only create confusion.
Still if some want to use it please don't hesitate to contact me (it got nice complexity property).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.