Skip to content
Permalink
Browse files

udpate to latest API

  • Loading branch information...
NicolasDP committed Mar 12, 2019
1 parent a533c9c commit ac53b8ee2ff412272115e33b9166d626d2c9d645

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -24,113 +24,7 @@ impl Ledger {
}
}

impl property::Ledger for Ledger {
type Update = TransactionsDiff;
type Error = Error;
type Transaction = SignedTransaction<Address>;

fn input<'a>(
&'a self,
input: &<self::SignedTransaction<Address> as property::Transaction>::Input,
) -> Result<&'a <self::SignedTransaction<Address> as property::Transaction>::Output, Self::Error>
{
match self.unspent_outputs.get(&input) {
Some(output) => Ok(output),
None => Err(Error::InputDoesNotResolve(*input)),
}
}

fn diff_transaction(
&self,
transaction: &SignedTransaction<Address>,
) -> Result<Self::Update, Self::Error> {
use chain_core::property::Transaction;

let mut diff = <Self::Update as property::Update>::empty();
let id = transaction.id();

// FIXME: check that inputs is non-empty?

// 0. verify that number of signatures matches number of
// transactions
if transaction.transaction.inputs.len() > transaction.witnesses.len() {
return Err(Error::NotEnoughSignatures(
transaction.transaction.inputs.len(),
transaction.witnesses.len(),
));
}

// 1. validate transaction without looking into the context
// and that each input is validated by the matching key.
for (input, witness) in transaction
.transaction
.inputs
.iter()
.zip(transaction.witnesses.iter())
{
let associated_output = self.input(input)?;

if witness.verifies(
// TODO: when we have the crypto unified we should not need
// the clone here anymore
&associated_output.0.public_key().unwrap().clone(),
&transaction.transaction.id(),
) == chain_crypto::Verification::Failed
{
return Err(Error::InvalidSignature(
input.clone(),
associated_output.clone(),
witness.clone(),
));
}
if let Some(output) = diff.spent_outputs.insert(*input, associated_output.clone()) {
return Err(Error::DoubleSpend(*input, output));
}
}

// 2. prepare to add the new outputs
for (index, output) in transaction.transaction.outputs.iter().enumerate() {
// Reject zero-valued outputs.
if output.1 == Value(0) {
return Err(Error::ZeroOutput(output.clone()));
}
diff.new_unspent_outputs.insert(
UtxoPointer::new(id, index as TransactionIndex, output.1),
output.clone(),
);
}

// 3. verify that transaction sum is zero.
let spent = diff
.spent_outputs
.iter()
.fold(0, |acc, (_, Output(_, Value(x)))| acc + x);
let new_unspent = diff
.new_unspent_outputs
.iter()
.fold(0, |acc, (_, Output(_, Value(x)))| acc + x);
if spent != new_unspent {
return Err(Error::TransactionSumIsNonZero(spent, new_unspent));
}
Ok(diff)
}

fn apply(&mut self, diff: Self::Update) -> Result<&mut Self, Self::Error> {
for spent_output in diff.spent_outputs.keys() {
if let None = self.unspent_outputs.remove(spent_output) {
return Err(Error::InputDoesNotResolve(*spent_output));
}
}

for (input, output) in diff.new_unspent_outputs {
if let Some(original_output) = self.unspent_outputs.insert(input, output.clone()) {
return Err(Error::InputWasAlreadySet(input, original_output, output));
}
}

Ok(self)
}
}
/*
#[cfg(test)]
pub mod test {
@@ -259,3 +153,4 @@ pub mod test {
)
}
}
*.
@@ -6,8 +6,8 @@ pub mod account;
pub mod block;
pub mod certificate;
mod date;
#[cfg(test)]
pub mod environment;
// #[cfg(test)]
// pub mod environment;
pub mod error;
pub mod key;
pub mod leadership;
@@ -21,18 +21,4 @@ pub mod utxo;
pub mod value;

#[cfg(test)]
mod tests {
use crate::ledger::Ledger;
use crate::transaction::SignedTransaction;
use chain_addr::Address;
use chain_core::property::testing;
use quickcheck::TestResult;

quickcheck! {
/// Randomly generated transaction should fail.
fn prop_bad_tx_fails(l: Ledger, tx: SignedTransaction<Address>) -> TestResult {
testing::prop_bad_transaction_fails(l, &tx)
}
}

}
mod tests {}
@@ -137,73 +137,9 @@ impl std::fmt::Display for Error {
impl std::error::Error for Error {}

impl property::Settings for Settings {
type Update = SettingsDiff;
type Error = Error;
type Block = crate::block::Block;

fn diff(&self, input: &Self::Block) -> Result<Self::Update, Self::Error> {
use chain_core::property::Block;

let mut update = <Self::Update as property::Update>::empty();

update.block_id = ValueDiff::Replace(self.last_block_id.clone(), input.id());

for msg in input.contents.iter() {
if let Message::Update(proposal) = msg {
if let Some(_max_number_of_transactions_per_block) =
proposal.max_number_of_transactions_per_block
{
/*
update.max_number_of_transactions_per_block = ValueDiff::Replace(
self.max_number_of_transactions_per_block,
max_number_of_transactions_per_block,
);
*/
unimplemented!()
}

if let Some(bootstrap_key_slots_percentage) =
proposal.bootstrap_key_slots_percentage
{
update.bootstrap_key_slots_percentage = ValueDiff::Replace(
self.bootstrap_key_slots_percentage,
bootstrap_key_slots_percentage,
);
}

if let Some(block_version) = proposal.block_version {
update.block_version = ValueDiff::Replace(self.block_version, block_version);
}
}
}

Ok(update)
}

fn apply(&mut self, update: Self::Update) -> Result<(), Self::Error> {
if !update.block_id.check(&self.last_block_id) {
match update.block_id {
ValueDiff::Replace(old, _) => {
return Err(Error::InvalidCurrentBlockId(self.last_block_id, old));
}
_ => unreachable!(),
}
}

if !update
.bootstrap_key_slots_percentage
.check(&self.bootstrap_key_slots_percentage)
{
return Err(Error::UpdateIsInvalid);
}

update.block_id.apply_to(&mut self.last_block_id);
update
.bootstrap_key_slots_percentage
.apply_to(&mut self.bootstrap_key_slots_percentage);
Ok(())
}

fn tip(&self) -> <Self::Block as property::Block>::Id {
self.last_block_id.clone()
}
@@ -1,5 +1,4 @@
use crate::key::{deserialize_public_key, serialize_public_key};
use crate::ledger::Ledger;
use crate::value::Value;
use chain_addr::Kind;
use chain_core::property;
@@ -9,7 +9,6 @@ use chain_core::property;

pub(crate) type Leadership = Box<
dyn property::LeaderSelection<
Update = leadership::Update,
Block = block::Block,
Error = leadership::Error,
LeaderId = leadership::PublicLeader,

0 comments on commit ac53b8e

Please sign in to comment.
You can’t perform that action at this time.