-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Make contract a separate runtime module #345
Changes from 1 commit
8bb5143
7fa574f
8c06e98
f315ca0
799e591
92922fd
d43ab98
92cfeeb
a4264f3
9d07af9
00919a4
900c859
593d51c
0b501c6
ce0e128
8915d76
ca48073
3f2423f
32b0e55
8577fad
14ee2f4
3a218d9
e8157c6
43508cd
a4b6480
a340742
e3b906c
8a541a3
77ee25b
30a72d3
51ee15d
9c1c246
3d3a4b7
6ccefe6
856de95
b3c256b
18a36a3
1872173
8be77ad
0df8491
25492de
f3a2ebf
ea2254d
315c0ea
3ab381c
b513597
cdb2eeb
d54cec0
4032b2f
3dfd294
f276d52
42d3fb8
75631f6
c2bc86d
bf07b3c
952112c
fa8991e
3e70be5
87c5b12
f15ac41
41f33b7
cb6e995
8e5f297
b16fec1
6072034
5bd0ee9
dadf9d8
6c93532
b84d090
259a32f
525df4b
8562de6
4122f48
f9497dd
7bf7759
de095a6
338fe9f
4377497
8ce5aed
d8fa9e4
a1ecfb0
91371c9
4dfc7dc
2348c18
5873335
62b498d
895386d
3e92676
ee97b9e
34189ee
a18292a
81e6eb7
9a52a44
d91dfbe
ee83701
f570351
4de767b
58878a8
7a712e1
eeebaba
595e534
a846bb1
3afe59a
dae4d40
9e13c68
d6c6250
af99a9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,10 @@ | |
| use super::{CodeOf, ContractAddressFor, Trait}; | ||
| use account_db::{AccountDb, ChangeSet, OverlayAccountDb}; | ||
| use rstd::prelude::*; | ||
| use runtime_primitives::traits::Zero; | ||
| use runtime_support::StorageMap; | ||
| use staking; | ||
| use system; | ||
| use vm; | ||
|
|
||
| //pub struct TransactionData { | ||
|
|
@@ -48,7 +51,7 @@ impl<'a, 'b: 'a, T: Trait> ExecutionContext<'a, 'b, T> { | |
| pub fn call( | ||
| &mut self, | ||
| dest: T::AccountId, | ||
| _value: T::Balance, | ||
| value: T::Balance, | ||
| gas_limit: u64, | ||
| _data: Vec<u8>, | ||
|
||
| ) -> Result<vm::ExecutionResult, ()> { | ||
|
|
@@ -57,9 +60,13 @@ impl<'a, 'b: 'a, T: Trait> ExecutionContext<'a, 'b, T> { | |
| // TODO: transfer `_value` using `overlay`. Return an error if failed. | ||
| // TODO: check the new depth | ||
|
|
||
| let (exec_result, change_set) = if !dest_code.is_empty() { | ||
| let (exec_result, change_set) = { | ||
| let mut overlay = OverlayAccountDb::new(self.account_db); | ||
| let exec_result = { | ||
|
|
||
| // TODO: It would be nice to propogate the error. | ||
| transfer(&self.self_account, &dest, value, &mut overlay).map_err(|_| ())?; | ||
|
|
||
| let exec_result = if !dest_code.is_empty() { | ||
| let mut nested = ExecutionContext { | ||
| account_db: &mut overlay, | ||
| _caller: self.self_account.clone(), | ||
|
|
@@ -68,21 +75,18 @@ impl<'a, 'b: 'a, T: Trait> ExecutionContext<'a, 'b, T> { | |
| depth: self.depth + 1, | ||
| }; | ||
| vm::execute(&dest_code, &mut nested, gas_limit).map_err(|_| ())? | ||
| }; | ||
|
|
||
| // TODO: Need to propagate gas_left. | ||
| // TODO: Need to return result buffer. | ||
|
|
||
| (exec_result, overlay.into_change_set()) | ||
| } else { | ||
| // that was a plain transfer | ||
| ( | ||
| } else { | ||
| // that was a plain transfer | ||
| vm::ExecutionResult { | ||
| gas_left: gas_limit, | ||
| return_data: Vec::new(), | ||
| }, | ||
| ChangeSet::new(), | ||
| ) | ||
| } | ||
| }; | ||
|
|
||
| (exec_result, overlay.into_change_set()) | ||
| }; | ||
|
|
||
| self.account_db.commit(change_set); | ||
|
|
@@ -132,6 +136,44 @@ impl<'a, 'b: 'a, T: Trait> ExecutionContext<'a, 'b, T> { | |
| } | ||
| } | ||
|
|
||
| fn transfer<T: Trait>( | ||
| transactor: &T::AccountId, | ||
| dest: &T::AccountId, | ||
| value: T::Balance, | ||
| overlay: &mut OverlayAccountDb<T>, | ||
| ) -> Result<(), &'static str> { | ||
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
Sorry, something went wrong. |
||
| let would_create = overlay.get_balance(transactor).is_zero(); | ||
| let fee = if would_create { | ||
| <staking::Module<T>>::creation_fee() | ||
| } else { | ||
| <staking::Module<T>>::transfer_fee() | ||
| }; | ||
| let liability = value + fee; | ||
|
|
||
| let from_balance = overlay.get_balance(transactor); | ||
| if from_balance < liability { | ||
| return Err("balance too low to send value"); | ||
| } | ||
| if would_create && value < <staking::Module<T>>::existential_deposit() { | ||
| return Err("value too low to create account"); | ||
| } | ||
| if <staking::Module<T>>::bondage(transactor) > <system::Module<T>>::block_number() { | ||
| return Err("bondage too high to send value"); | ||
| } | ||
|
|
||
| let to_balance = overlay.get_balance(dest); | ||
| if to_balance + value <= to_balance { | ||
|
||
| return Err("destination balance too high to receive value"); | ||
| } | ||
|
|
||
| if transactor != dest { | ||
| overlay.set_balance(transactor, from_balance - liability); | ||
| overlay.set_balance(dest, to_balance + value); | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| impl<'a, 'b: 'a, T: Trait + 'b> vm::Ext for ExecutionContext<'a, 'b, T> { | ||
| type AccountId = T::AccountId; | ||
| type Balance = T::Balance; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why a let first instead of putting it into one line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is intentional: I think
if set_free_balance(addr, balance) { continue }is too obscure.
However, I think adding something like
if set_free_balance(addr, balance) == FreeBalanceResult::Killed { continue }would be much better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!