1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use common_types::{
BlockNumber,
header::Header,
engines::params::CommonParams,
errors::VapcoreError as Error,
};
use enjen::Engine;
use block_reward::{self, RewardKind};
use vapory_types::U256;
use mashina::{
ExecutedBlock,
Machine,
};
use common_types::{
ancestry_action::AncestryAction,
header::ExtendedHeader,
snapshot::Snapshotting
};
#[derive(Clone, Default)]
pub struct NullEngineParams {
pub block_reward: U256,
pub immediate_finalization: bool
}
impl From<vapjson::spec::NullEngineParams> for NullEngineParams {
fn from(p: vapjson::spec::NullEngineParams) -> Self {
NullEngineParams {
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
immediate_finalization: p.immediate_finalization.unwrap_or(false)
}
}
}
pub struct NullEngine {
params: NullEngineParams,
mashina: Machine,
}
impl NullEngine {
pub fn new(params: NullEngineParams, mashina: Machine) -> Self {
NullEngine {
params,
mashina,
}
}
}
impl Engine for NullEngine {
fn name(&self) -> &str { "NullEngine" }
fn mashina(&self) -> &Machine { &self.mashina }
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
fn on_close_block(
&self,
block: &mut ExecutedBlock,
_parent_header: &Header
) -> Result<(), Error> {
use std::ops::Shr;
let author = *block.header.author();
let number = block.header.number();
let reward = self.params.block_reward;
if reward == U256::zero() { return Ok(()) }
let n_uncles = block.uncles.len();
let mut rewards = Vec::new();
let result_block_reward = reward + reward.shr(5) * U256::from(n_uncles);
rewards.push((author, RewardKind::Author, result_block_reward));
for u in &block.uncles {
let uncle_author = u.author();
let result_uncle_reward = (reward * U256::from(8 + u.number() - number)).shr(3);
rewards.push((*uncle_author, RewardKind::uncle(number, u.number()), result_uncle_reward));
}
block_reward::apply_block_rewards(&rewards, block, &self.mashina)
}
fn verify_local_seal(&self, _header: &Header) -> Result<(), Error> {
Ok(())
}
fn snapshot_mode(&self) -> Snapshotting {
Snapshotting::PoW { blocks: 10_000, max_restore_blocks: 10_000 }
}
fn params(&self) -> &CommonParams {
self.mashina.params()
}
fn ancestry_actions(&self, _header: &Header, ancestry: &mut dyn Iterator<Item=ExtendedHeader>) -> Vec<AncestryAction> {
if self.params.immediate_finalization {
ancestry.take(1).map(|e| AncestryAction::MarkFinalized(e.header.hash())).collect()
} else {
Vec::new()
}
}
}