diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index f8c6bab59d162dc290c4514f70fa0e8a162acfe7..1002d1c894e1609db027f532fbf6a2cc1e195f5f 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -4318,20 +4318,6 @@ dependencies = [
  "sp-std",
 ]
 
-[[package]]
-name = "pallet-benchmark"
-version = "2.0.0-rc6"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "serde",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
 [[package]]
 name = "pallet-collective"
 version = "2.0.0-rc6"
diff --git a/substrate/Cargo.toml b/substrate/Cargo.toml
index e69a95f1e4a646e68730ff087545f99b26bd83c1..99b1d418a5153c19ab2dc3a39d233c43fc7c8b7c 100644
--- a/substrate/Cargo.toml
+++ b/substrate/Cargo.toml
@@ -66,7 +66,6 @@ members = [
 	"frame/babe",
 	"frame/balances",
 	"frame/benchmarking",
-	"frame/benchmark",
 	"frame/collective",
 	"frame/contracts",
 	"frame/contracts/rpc",
diff --git a/substrate/frame/benchmark/Cargo.toml b/substrate/frame/benchmark/Cargo.toml
deleted file mode 100644
index f731ebcbacf54583dcc19695243adda3c00b94c3..0000000000000000000000000000000000000000
--- a/substrate/frame/benchmark/Cargo.toml
+++ /dev/null
@@ -1,36 +0,0 @@
-[package]
-name = "pallet-benchmark"
-version = "2.0.0-rc6"
-authors = ["Parity Technologies <admin@parity.io>"]
-edition = "2018"
-license = "Apache-2.0"
-homepage = "https://substrate.dev"
-repository = "https://github.com/paritytech/substrate/"
-description = "Patterns to benchmark in a FRAME runtime."
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[dependencies]
-serde = { version = "1.0.101", optional = true }
-codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
-sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" }
-sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" }
-sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" }
-frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" }
-frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" }
-frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true }
-
-[features]
-default = ["std"]
-std = [
-	"serde",
-	"codec/std",
-	"sp-std/std",
-	"sp-io/std",
-	"sp-runtime/std",
-	"frame-support/std",
-	"frame-system/std",
-	"frame-benchmarking/std",
-]
-runtime-benchmarks = ["frame-benchmarking"]
diff --git a/substrate/frame/benchmark/README.md b/substrate/frame/benchmark/README.md
deleted file mode 100644
index e00e11292e1432fd26b397b5c80d9f0627e9554f..0000000000000000000000000000000000000000
--- a/substrate/frame/benchmark/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-A pallet that contains common runtime patterns in an isolated manner.
-This pallet is **not** meant to be used in a production blockchain, just
-for benchmarking and testing purposes.
-
-License: Apache-2.0
\ No newline at end of file
diff --git a/substrate/frame/benchmark/src/benchmarking.rs b/substrate/frame/benchmark/src/benchmarking.rs
deleted file mode 100644
index ddf3df9eaad4cb5a367724a5b2b1508359856bc4..0000000000000000000000000000000000000000
--- a/substrate/frame/benchmark/src/benchmarking.rs
+++ /dev/null
@@ -1,134 +0,0 @@
-// This file is part of Substrate.
-
-// Copyright (C) 2020 Parity Technologies (UK) Ltd.
-// SPDX-License-Identifier: Apache-2.0
-
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// 	http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//! Benchmarks for common FRAME Pallet operations.
-
-#![cfg(feature = "runtime-benchmarks")]
-
-use super::*;
-
-use frame_system::RawOrigin;
-use sp_std::prelude::*;
-use frame_benchmarking::{benchmarks, account};
-
-use crate::Module as Benchmark;
-
-const SEED: u32 = 0;
-
-benchmarks! {
-	_ {
-		let m in 1 .. 1000 => {
-			let origin = RawOrigin::Signed(account("member", m, SEED));
-			Benchmark::<T>::add_member_list(origin.into())?
-		};
-		let i in 1 .. 1000 => {
-			MyMap::insert(i, i);
-		};
-		let d in 1 .. 1000 => {
-			for i in 0..d {
-				for j in 0..100 {
-					MyDoubleMap::insert(i, j, d);
-				}
-			}
-		};
-	}
-
-	add_member_list {
-		let m in ...;
-	}: _(RawOrigin::Signed(account("member", m + 1, SEED)))
-
-	append_member_list {
-		let m in ...;
-	}: _(RawOrigin::Signed(account("member", m + 1, SEED)))
-
-	read_value {
-		let n in 1 .. 1000;
-		MyValue::put(n);
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), n)
-
-	put_value {
-		let n in 1 .. 1000;
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), n)
-
-	exists_value {
-		let n in 1 .. 1000;
-		MyValue::put(n);
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), n)
-
-	remove_value {
-		let i in ...;
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), i)
-
-	read_map {
-		let i in ...;
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), i)
-
-	insert_map {
-		let n in 1 .. 1000;
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), n)
-
-	contains_key_map {
-		let i in ...;
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), i)
-
-	remove_prefix {
-		let d in ...;
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), d)
-
-	do_nothing {
-		let n in 1 .. 1000;
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), n)
-
-	encode_accounts {
-		let a in 1 .. 1000;
-		let mut accounts = Vec::new();
-		for _ in 0..a {
-			accounts.push(account::<T::AccountId>("encode", a, SEED));
-		}
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), accounts)
-
-	decode_accounts {
-		let a in 1 .. 1000;
-		let mut accounts = Vec::new();
-		for _ in 0..a {
-			accounts.push(account::<T::AccountId>("encode", a, SEED));
-		}
-		let bytes = accounts.encode();
-	}: _(RawOrigin::Signed(account("user", 0, SEED)), bytes)
-
-	// Custom implementation to handle benchmarking of storage recalculation.
-	// Puts `repeat` number of items into random storage keys, and then times how
-	// long it takes to recalculate the storage root.
-	storage_root {
-		let z in 0 .. 10000;
-	}: {
-		for index in 0 .. z {
-			let random = (index).using_encoded(sp_io::hashing::blake2_256);
-			sp_io::storage::set(&random, &random);
-		}
-	}
-
-	// Custom implementation to handle benchmarking of calling a host function.
-	// Will check how long it takes to call `current_time()`.
-	current_time {
-		let z in 0 .. 1000;
-	}: {
-		for _ in 0 .. z {
-			let _ = frame_benchmarking::benchmarking::current_time();
-		}
-	}
-}
diff --git a/substrate/frame/benchmark/src/lib.rs b/substrate/frame/benchmark/src/lib.rs
deleted file mode 100644
index 422272f817c7a2f75c2b991a40a01929b4dc48b2..0000000000000000000000000000000000000000
--- a/substrate/frame/benchmark/src/lib.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-// This file is part of Substrate.
-
-// Copyright (C) 2020 Parity Technologies (UK) Ltd.
-// SPDX-License-Identifier: Apache-2.0
-
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// 	http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//! A pallet that contains common runtime patterns in an isolated manner.
-//! This pallet is **not** meant to be used in a production blockchain, just
-//! for benchmarking and testing purposes.
-
-#![cfg_attr(not(feature = "std"), no_std)]
-
-use frame_support::{decl_module, decl_storage, decl_event, decl_error};
-use frame_support::traits::Currency;
-use frame_system::{self as system, ensure_signed};
-use codec::{Encode, Decode};
-use sp_std::prelude::Vec;
-
-mod benchmarking;
-
-/// Type alias for currency balance.
-pub type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
-
-/// The pallet's configuration trait.
-pub trait Trait: system::Trait {
-	type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
-	type Currency: Currency<Self::AccountId>;
-}
-
-// This pallet's storage items.
-decl_storage! {
-	trait Store for Module<T: Trait> as Benchmark {
-		MyMemberList: Vec<T::AccountId>;
-		MyMemberMap: map hasher(blake2_128_concat) T::AccountId => bool;
-		MyValue: u32;
-		MyMap: map hasher(twox_64_concat) u32 => u32;
-		MyDoubleMap: double_map hasher(twox_64_concat) u32, hasher(identity) u32 => u32;
-	}
-}
-
-// The pallet's events
-decl_event!(
-	pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
-		Dummy(u32, AccountId),
-	}
-);
-
-// The pallet's errors
-decl_error! {
-	pub enum Error for Module<T: Trait> {
-	}
-}
-
-// The pallet's dispatchable functions.
-decl_module! {
-	/// The module declaration.
-	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		type Error = Error<T>;
-
-		fn deposit_event() = default;
-
-		/// Do nothing.
-		#[weight = 0]
-		pub fn do_nothing(_origin, input: u32) {
-			if input > 0 {
-				return Ok(());
-			}
-		}
-
-		/// Read a value from storage value `repeat` number of times.
-		/// Note the first `get()` read here will pull from the underlying
-		/// storage database, however, the `repeat` calls will all pull from the
-		/// storage overlay cache. You must consider this when analyzing the
-		/// results of the benchmark.
-		#[weight = 0]
-		pub fn read_value(_origin, repeat: u32) {
-			for _ in 0..repeat {
-				MyValue::get();
-			}
-		}
-
-		/// Put a value into a storage value.
-		#[weight = 0]
-		pub fn put_value(_origin, repeat: u32) {
-			for r in 0..repeat {
-				MyValue::put(r);
-			}
-		}
-
-		/// Read a value from storage `repeat` number of times.
-		/// Note the first `exists()` read here will pull from the underlying
-		/// storage database, however, the `repeat` calls will all pull from the
-		/// storage overlay cache. You must consider this when analyzing the
-		/// results of the benchmark.
-		#[weight = 0]
-		pub fn exists_value(_origin, repeat: u32) {
-			for _ in 0..repeat {
-				MyValue::exists();
-			}
-		}
-
-		/// Remove a value from storage `repeat` number of times.
-		#[weight = 0]
-		pub fn remove_value(_origin, repeat: u32) {
-			for r in 0..repeat {
-				MyMap::remove(r);
-			}
-		}
-
-		/// Read a value from storage map `repeat` number of times.
-		#[weight = 0]
-		pub fn read_map(_origin, repeat: u32) {
-			for r in 0..repeat {
-				MyMap::get(r);
-			}
-		}
-
-		/// Insert a value into a map.
-		#[weight = 0]
-		pub fn insert_map(_origin, repeat: u32) {
-			for r in 0..repeat {
-				MyMap::insert(r, r);
-			}
-		}
-
-		/// Check is a map contains a value `repeat` number of times.
-		#[weight = 0]
-		pub fn contains_key_map(_origin, repeat: u32) {
-			for r in 0..repeat {
-				MyMap::contains_key(r);
-			}
-		}
-
-		/// Read a value from storage `repeat` number of times.
-		#[weight = 0]
-		pub fn remove_prefix(_origin, repeat: u32) {
-			for r in 0..repeat {
-				MyDoubleMap::remove_prefix(r);
-			}
-		}
-
-		/// Add user to the list.
-		#[weight = 0]
-		pub fn add_member_list(origin) {
-			let who = ensure_signed(origin)?;
-			MyMemberList::<T>::mutate(|x| x.push(who));
-		}
-
-		/// Append user to the list.
-		#[weight = 0]
-		pub fn append_member_list(origin) {
-			let who = ensure_signed(origin)?;
-			MyMemberList::<T>::append(who);
-		}
-
-		/// Encode a vector of accounts to bytes.
-		#[weight = 0]
-		pub fn encode_accounts(_origin, accounts: Vec<T::AccountId>) {
-			let bytes = accounts.encode();
-
-			// In an attempt to tell the compiler not to optimize away this benchmark, we will use
-			// the result of encoding the accounts.
-			if bytes.is_empty() {
-				frame_support::print("You are encoding zero accounts.");
-			}
-		}
-
-		/// Decode bytes into a vector of accounts.
-		#[weight = 0]
-		pub fn decode_accounts(_origin, bytes: Vec<u8>) {
-			let accounts: Vec<T::AccountId> = Decode::decode(&mut bytes.as_slice()).map_err(|_| "Could not decode")?;
-
-			// In an attempt to tell the compiler not to optimize away this benchmark, we will use
-			// the result of decoding the bytes.
-			if accounts.is_empty() {
-				frame_support::print("You are decoding zero bytes.");
-			}
-		}
-	}
-}
diff --git a/substrate/frame/benchmarking/README.md b/substrate/frame/benchmarking/README.md
index 1e06135e345e7317585be196c13440c9a98e0cbb..bf4bf951aa2b201e331799c85b401e0ae0f643db 100644
--- a/substrate/frame/benchmarking/README.md
+++ b/substrate/frame/benchmarking/README.md
@@ -1,3 +1,188 @@
-Macro for benchmarking a FRAME runtime.
+# Substrate Runtime Benchmarking Framework
 
-License: Apache-2.0
\ No newline at end of file
+This crate contains a set of utilities that can be used to benchmark and weigh FRAME pallets that
+you develop for your Substrate Runtime.
+
+## Overview
+
+Substrate's FRAME framework allows you to develop custom logic for your blockchain that can be
+included in your runtime. This flexibility is key to help you design complex and interactive
+pallets, but without accurate weights assigned to dispatchables, your blockchain may become
+vulnerable to denial of service (DoS) attacks by malicious actors.
+
+The Substrate Runtime Benchmarking Framework is a tool you can use to mitigate DoS attacks against
+your blockchain network by benchmarking the computational resources required to execute different
+functions in the runtime, for example extrinsics, `on_initialize`, `verify_unsigned`, etc...
+
+The general philosophy behind the benchmarking system is: If your node can know ahead of time how
+long it will take to execute an extrinsic, it can safely make decisions to include or exclude that
+extrinsic based on its available resources. By doing this, it can keep the block production and
+import process running smoothly.
+
+To achieve this, we need to model how long it takes to run each function in the runtime by:
+
+* Creating custom benchmarking logic that executes a specific code path of a function.
+* Executing the benchmark in the Wasm execution environment, on a specific set of hardware, with a
+  custom runtime configuration, etc...
+* Executing the benchmark across controlled ranges of possible values that may affect the result of
+  the benchmark (called "components").
+* Executing the benchmark multiple times at each point in order to isolate and remove outliers.
+* Using the results of the benchmark to create a linear model of the function across its components.
+
+With this linear model, we are able to estimate ahead of time how long it takes to execute some
+logic, and thus make informed decisions without actually spending any significant resources at
+runtime.
+
+Note that we assume that all extrinsics are assumed to be of linear complexity, which is why we are
+able to always fit them to a linear model. Quadratic or higher complexity functions are, in general,
+considered to be dangerous to the runtime as the weight of these functions may explode as the
+runtime state or input becomes too complex.
+
+The benchmarking framework comes with the following tools:
+
+* [A set of macros](./src/lib.rs) (`benchmarks!`, `add_benchmark!`, etc...) to make it easy to
+  write, test, and add runtime benchmarks.
+* [A set of linear regression analysis functions](./src/analysis.rs) for processing benchmark data.
+* [A CLI extension](../../utils/benchmarking-cli/) to make it easy to execute benchmarks on your
+  node.
+
+The end-to-end benchmarking pipeline is disabled by default when compiling a node. If you want to
+run benchmarks, you need to enable it by compiling with a Rust feature flag `runtime-benchmarks`.
+More details about this below.
+
+### Weight
+
+Substrate represents computational resources using a generic unit of measurement called "Weight". It
+defines 10^12 Weight as 1 second of computation on the physical machine used for benchmarking. This
+means that the weight of a function may change based on the specific hardware used to benchmark the
+runtime functions.
+
+By modeling the expected weight of each runtime function, the blockchain is able to calculate how
+many transactions or system level functions it will be able to execute within a certain period of
+time. Often, the limiting factor for a blockchain is the fixed block production time for the
+network.
+
+Within FRAME, each dispatchable function must have a `#[weight]` annotation with a function that can
+return the expected weight for the worst case scenario execution of that function given its inputs.
+This benchmarking framework will result in a file that automatically generates those formulas for
+you, which you can then use in your pallet.
+
+## Writing Benchmarks
+
+Writing a runtime benchmark is much like writing a unit test for your pallet. It needs to be
+carefully crafted to execute a certain logical path in your code. In tests you want to check for
+various success and failure conditions, but with benchmarks you specifically look for the **most
+computationally heavy** path, a.k.a the "worst case scenario".
+
+This means that if there are certain storage items or runtime state that may affect the complexity
+of the function, for example triggering more iterations in a `for` loop, to get an accurate result,
+you must set up your benchmark to trigger this.
+
+It may be that there are multiple paths your function can go down, and it is not clear which one is
+the heaviest. In this case, you should just create a benchmark for each scenario! You may find that
+there are paths in your code where complexity may become unbounded depending on user input. This may
+be a hint that you should enforce sane boundaries for how a user can use your pallet. For example:
+limiting the number of elements in a vector, limiting the number of iterations in a `for` loop,
+etc...
+
+Examples of end-to-end benchmarks can be found in the [pallets provided by Substrate](../), and the
+specific details on how to use the `benchmarks!` macro can be found in [its
+documentation](./src/lib.rs).
+
+## Testing Benchmarks
+
+You can test your benchmarks using the same test runtime that you created for your pallet's unit
+tests. By creating your benchmarks in the `benchmarks!` macro, it automatically generates test
+functions for you:
+
+```rust
+fn test_benchmark_[benchmark_name]<T>::() -> Result<(), &'static str>
+```
+
+Simply add these functions to a unit test and ensure that the result of the function is `Ok(())`.
+
+> **Note:** If your test runtime and production runtime have different configurations, you may get
+different results when testing your benchmark and actually running it.
+
+In general, benchmarks returning `Ok(())` is all you need to check for since it signals the executed
+extrinsic has completed successfully. However, you can optionally include a `verify` block with your
+benchmark, which can additionally verify any final conditions, such as the final state of your
+runtime.
+
+These additional `verify` blocks will not affect the results of your final benchmarking process.
+
+To run the tests, you need to enable the `runtime-benchmarks` feature flag. This may also mean you
+need to move into your node's binary folder. For example, with the Substrate repository, this is how
+you would test the Balances pallet's benchmarks:
+
+```bash
+cd bin/node/cli
+cargo test -p pallet-balances --features runtime-benchmarks
+```
+
+## Adding Benchmarks
+
+The benchmarks included with each pallet are not automatically added to your node. To actually
+execute these benchmarks, you need to implement the `frame_benchmarking::Benchmark` trait. You can
+see an example of how to do this in the [included Substrate
+node](../../bin/node/runtime/src/lib.rs).
+
+Assuming there are already some benchmarks set up on your node, you just need to add another
+instance of the `add_benchmark!` macro:
+
+```rust
+///  configuration for running benchmarks
+///               |    name of your pallet's crate (as imported)
+///               v                   v
+add_benchmark!(params, batches, pallet_balances, Balances);
+///                       ^                          ^
+///    where all benchmark results are saved         |
+///            the `struct` created for your pallet by `construct_runtime!`
+```
+
+Once you have done this, you will need to compile your node binary with the `runtime-benchmarks`
+feature flag:
+
+```bash
+cd bin/node/cli
+cargo build --release --features runtime-benchmarks
+```
+
+## Running Benchmarks
+
+Finally, once you have a node binary with benchmarks enabled, you need to execute your various
+benchmarks.
+
+You can get a list of the available benchmarks by running:
+
+```bash
+./target/release/substrate benchmark --chain dev --pallet "*" --extrinsic "*" --repeat 0
+```
+
+Then you can run a benchmark like so:
+
+```bash
+./target/release/substrate benchmark \
+    --chain dev \               # Configurable Chain Spec
+    --execution=wasm \          # Always test with Wasm
+    --wasm-execution=compiled \ # Always used `wasm-time`
+    --pallet pallet_balances \  # Select the pallet
+    --extrinsic transfer \      # Select the extrinsic
+    --steps 50 \                # Number of samples across component ranges
+    --repeat 20 \               # Number of times we repeat a benchmark
+    --output \                  # Output benchmark results into a Rust file
+```
+
+This will output a file `pallet_name.rs` which implements the `WeightInfo` trait you should include
+in your pallet. Each blockchain should generate their own benchmark file with their custom
+implementation of the `WeightInfo` trait. This means that you will be able to use these modular
+Substrate pallets while still keeping your network safe for your specific configuration and
+requirements.
+
+To get a full list of available options when running benchmarks, run:
+
+```bash
+./target/release/substrate benchmark --help
+```
+
+License: Apache-2.0
diff --git a/substrate/frame/benchmarking/src/analysis.rs b/substrate/frame/benchmarking/src/analysis.rs
index 6963d84ee614e20f94906099244d439092d86358..dafb4a74b669fef3c90330acae1ae32e27d1712f 100644
--- a/substrate/frame/benchmarking/src/analysis.rs
+++ b/substrate/frame/benchmarking/src/analysis.rs
@@ -15,7 +15,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! Tools for analysing the benchmark results.
+//! Tools for analyzing the benchmark results.
 
 use std::collections::BTreeMap;
 use linregress::{FormulaRegressionBuilder, RegressionDataBuilder, RegressionModel};
diff --git a/substrate/frame/benchmarking/src/lib.rs b/substrate/frame/benchmarking/src/lib.rs
index 6a457d2a5e912763a2bec4d1babbdb874ae2b5ec..b189cdb6e705e9ed8dc7ce68421c50f271b404eb 100644
--- a/substrate/frame/benchmarking/src/lib.rs
+++ b/substrate/frame/benchmarking/src/lib.rs
@@ -158,7 +158,7 @@ pub use sp_storage::TrackedStorageKey;
 /// }
 /// ```
 ///
-/// These `verify` blocks will not execute when running your actual benchmarks!
+/// These `verify` blocks will not affect your benchmark results!
 ///
 /// You can construct benchmark tests like so:
 ///