Add execute_with to TestExternalities (#3793)

This function executes the given closure in a context where the test
externalities are set. This makes the srml tests easier to write, as the
test externalities need to be created anyway.
This commit is contained in:
Bastian Köcher
2019-10-10 15:01:30 +02:00
committed by GitHub
parent 34c7338211
commit 4dbc9265ee
44 changed files with 2369 additions and 2645 deletions
+178 -203
View File
@@ -807,7 +807,6 @@ mod tests {
account_db::AccountDb, gas::GasMeter, tests::{ExtBuilder, Test},
exec::{ExecReturnValue, ExecError, STATUS_SUCCESS}, CodeHash, Config,
};
use sr_primitives::set_and_run_with_externalities;
use std::{cell::RefCell, rc::Rc, collections::HashMap, marker::PhantomData};
use assert_matches::assert_matches;
@@ -933,7 +932,7 @@ mod tests {
exec_success()
});
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap();
@@ -953,7 +952,7 @@ mod tests {
let dest = BOB;
// This test verifies that base fee for call is taken.
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let vm = MockVm::new();
let loader = MockLoader::empty();
let cfg = Config::preload();
@@ -971,7 +970,7 @@ mod tests {
});
// This test verifies that base fee for instantiation is taken.
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let mut loader = MockLoader::empty();
let code = loader.insert(|_| exec_success());
@@ -1001,7 +1000,7 @@ mod tests {
let vm = MockVm::new();
let loader = MockLoader::empty();
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.set_balance(&origin, 100);
@@ -1033,7 +1032,7 @@ mod tests {
|_| Ok(ExecReturnValue { status: 1, data: Vec::new() })
);
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap();
@@ -1061,93 +1060,84 @@ mod tests {
// This test sends 50 units of currency to a non-existent account.
// This should lead to creation of a new account thus
// a fee should be charged.
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let vm = MockVm::new();
let loader = MockLoader::empty();
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.set_balance(&origin, 100);
ctx.overlay.set_balance(&dest, 0);
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let vm = MockVm::new();
let loader = MockLoader::empty();
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.set_balance(&origin, 100);
ctx.overlay.set_balance(&dest, 0);
let mut gas_meter = GasMeter::<Test>::with_limit(1000, 1);
let mut gas_meter = GasMeter::<Test>::with_limit(1000, 1);
let result = ctx.call(dest, 50, &mut gas_meter, vec![]);
assert_matches!(result, Ok(_));
let result = ctx.call(dest, 50, &mut gas_meter, vec![]);
assert_matches!(result, Ok(_));
let mut toks = gas_meter.tokens().iter();
match_tokens!(
toks,
ExecFeeToken::Call,
TransferFeeToken {
kind: TransferFeeKind::AccountCreate,
gas_price: 1u64
},
);
},
);
let mut toks = gas_meter.tokens().iter();
match_tokens!(
toks,
ExecFeeToken::Call,
TransferFeeToken {
kind: TransferFeeKind::AccountCreate,
gas_price: 1u64
},
);
});
// This one is similar to the previous one but transfer to an existing account.
// In this test we expect that a regular transfer fee is charged.
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let vm = MockVm::new();
let loader = MockLoader::empty();
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.set_balance(&origin, 100);
ctx.overlay.set_balance(&dest, 15);
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let vm = MockVm::new();
let loader = MockLoader::empty();
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.set_balance(&origin, 100);
ctx.overlay.set_balance(&dest, 15);
let mut gas_meter = GasMeter::<Test>::with_limit(1000, 1);
let mut gas_meter = GasMeter::<Test>::with_limit(1000, 1);
let result = ctx.call(dest, 50, &mut gas_meter, vec![]);
assert_matches!(result, Ok(_));
let result = ctx.call(dest, 50, &mut gas_meter, vec![]);
assert_matches!(result, Ok(_));
let mut toks = gas_meter.tokens().iter();
match_tokens!(
toks,
ExecFeeToken::Call,
TransferFeeToken {
kind: TransferFeeKind::Transfer,
gas_price: 1u64
},
);
},
);
let mut toks = gas_meter.tokens().iter();
match_tokens!(
toks,
ExecFeeToken::Call,
TransferFeeToken {
kind: TransferFeeKind::Transfer,
gas_price: 1u64
},
);
});
// This test sends 50 units of currency as an endownment to a newly
// instantiated contract.
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let mut loader = MockLoader::empty();
let code = loader.insert(|_| exec_success());
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let mut loader = MockLoader::empty();
let code = loader.insert(|_| exec_success());
let vm = MockVm::new();
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
let vm = MockVm::new();
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.set_balance(&origin, 100);
ctx.overlay.set_balance(&dest, 15);
ctx.overlay.set_balance(&origin, 100);
ctx.overlay.set_balance(&dest, 15);
let mut gas_meter = GasMeter::<Test>::with_limit(1000, 1);
let mut gas_meter = GasMeter::<Test>::with_limit(1000, 1);
let result = ctx.instantiate(50, &mut gas_meter, &code, vec![]);
assert_matches!(result, Ok(_));
let result = ctx.instantiate(50, &mut gas_meter, &code, vec![]);
assert_matches!(result, Ok(_));
let mut toks = gas_meter.tokens().iter();
match_tokens!(
toks,
ExecFeeToken::Instantiate,
TransferFeeToken {
kind: TransferFeeKind::ContractInstantiate,
gas_price: 1u64
},
);
},
);
let mut toks = gas_meter.tokens().iter();
match_tokens!(
toks,
ExecFeeToken::Instantiate,
TransferFeeToken {
kind: TransferFeeKind::ContractInstantiate,
gas_price: 1u64
},
);
});
}
#[test]
@@ -1160,7 +1150,7 @@ mod tests {
let vm = MockVm::new();
let loader = MockLoader::empty();
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.set_balance(&origin, 0);
@@ -1194,7 +1184,7 @@ mod tests {
|_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![1, 2, 3, 4] })
);
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap();
@@ -1225,7 +1215,7 @@ mod tests {
|_| Ok(ExecReturnValue { status: 1, data: vec![1, 2, 3, 4] })
);
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap();
@@ -1253,7 +1243,7 @@ mod tests {
});
// This one tests passing the input data into a contract via call.
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.instantiate_contract(&BOB, input_data_ch).unwrap();
@@ -1278,7 +1268,7 @@ mod tests {
});
// This one tests passing the input data into a contract via instantiate.
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
@@ -1322,7 +1312,7 @@ mod tests {
exec_success()
});
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap();
@@ -1366,7 +1356,7 @@ mod tests {
exec_success()
});
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
@@ -1408,7 +1398,7 @@ mod tests {
exec_success()
});
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap();
@@ -1432,23 +1422,20 @@ mod tests {
let mut loader = MockLoader::empty();
let dummy_ch = loader.insert(|_| exec_success());
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
assert_matches!(
ctx.instantiate(
0, // <- zero endowment
&mut GasMeter::<Test>::with_limit(10000, 1),
&dummy_ch,
vec![],
),
Err(_)
);
}
);
assert_matches!(
ctx.instantiate(
0, // <- zero endowment
&mut GasMeter::<Test>::with_limit(10000, 1),
&dummy_ch,
vec![],
),
Err(_)
);
});
}
#[test]
@@ -1460,38 +1447,35 @@ mod tests {
|_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![80, 65, 83, 83] })
);
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
let instantiated_contract_address = assert_matches!(
ctx.instantiate(
100,
&mut GasMeter::<Test>::with_limit(10000, 1),
&dummy_ch,
vec![],
),
Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address
);
let instantiated_contract_address = assert_matches!(
ctx.instantiate(
100,
&mut GasMeter::<Test>::with_limit(10000, 1),
&dummy_ch,
vec![],
),
Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address
);
// Check that the newly created account has the expected code hash and
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100),
topics: Vec::new(),
},
DeferredAction::DepositEvent {
event: RawEvent::Instantiated(ALICE, instantiated_contract_address),
topics: Vec::new(),
}
]);
}
);
// Check that the newly created account has the expected code hash and
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100),
topics: Vec::new(),
},
DeferredAction::DepositEvent {
event: RawEvent::Instantiated(ALICE, instantiated_contract_address),
topics: Vec::new(),
}
]);
});
}
#[test]
@@ -1503,28 +1487,25 @@ mod tests {
|_| Ok(ExecReturnValue { status: 1, data: vec![70, 65, 73, 76] })
);
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
let instantiated_contract_address = assert_matches!(
ctx.instantiate(
100,
&mut GasMeter::<Test>::with_limit(10000, 1),
&dummy_ch,
vec![],
),
Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address
);
let instantiated_contract_address = assert_matches!(
ctx.instantiate(
100,
&mut GasMeter::<Test>::with_limit(10000, 1),
&dummy_ch,
vec![],
),
Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address
);
// Check that the account has not been created.
assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none());
assert!(ctx.events().is_empty());
}
);
// Check that the account has not been created.
assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none());
assert!(ctx.events().is_empty());
});
}
#[test]
@@ -1551,40 +1532,37 @@ mod tests {
}
});
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap();
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap();
assert_matches!(
ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]),
Ok(_)
);
assert_matches!(
ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]),
Ok(_)
);
let instantiated_contract_address = instantiated_contract_address.borrow().as_ref().unwrap().clone();
let instantiated_contract_address = instantiated_contract_address.borrow().as_ref().unwrap().clone();
// Check that the newly created account has the expected code hash and
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
DeferredAction::DepositEvent {
event: RawEvent::Transfer(BOB, instantiated_contract_address, 15),
topics: Vec::new(),
},
DeferredAction::DepositEvent {
event: RawEvent::Instantiated(BOB, instantiated_contract_address),
topics: Vec::new(),
},
]);
}
);
// Check that the newly created account has the expected code hash and
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
DeferredAction::DepositEvent {
event: RawEvent::Transfer(BOB, instantiated_contract_address, 15),
topics: Vec::new(),
},
DeferredAction::DepositEvent {
event: RawEvent::Instantiated(BOB, instantiated_contract_address),
topics: Vec::new(),
},
]);
});
}
#[test]
@@ -1613,29 +1591,26 @@ mod tests {
}
});
set_and_run_with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(),
|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap();
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000);
ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap();
assert_matches!(
ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]),
Ok(_)
);
assert_matches!(
ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]),
Ok(_)
);
// The contract wasn't instantiated so we don't expect to see an instantiation
// event here.
assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
]);
}
);
// The contract wasn't instantiated so we don't expect to see an instantiation
// event here.
assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
]);
});
}
#[test]
@@ -1649,7 +1624,7 @@ mod tests {
exec_success()
});
set_and_run_with_externalities(&mut ExtBuilder::default().build(), || {
ExtBuilder::default().build().execute_with(|| {
let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
File diff suppressed because it is too large Load Diff