Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ matrix:
- wasm-pack build
- wasm-pack test --firefox --headless
- wasm-pack test --firefox --headless --release
- wasm-pack test --chrome --headless
- wasm-pack test --chrome --headless --release
# - wasm-pack test --chrome --headless
# - wasm-pack test --chrome --headless --release

- name: JS tests
dist: bionic
Expand Down
2 changes: 1 addition & 1 deletion sigma-tree/src/chain/context_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::collections::HashMap;
use std::io;

/// User-defined variables to be put into context
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct ContextExtension {
/// key-value pairs of variable id and it's value
Expand Down
3 changes: 2 additions & 1 deletion sigma-tree/src/chain/data_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ use proptest_derive::Arbitrary;
use serde::{Deserialize, Serialize};

/// Inputs, that are used to enrich script context, but won't be spent by the transaction
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
#[cfg_attr(test, derive(Arbitrary))]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct DataInput {
/// id of the box to add into context (should be in UTXO)
#[cfg_attr(feature = "with-serde", serde(rename = "boxId"))]
pub box_id: BoxId,
}

Expand Down
29 changes: 26 additions & 3 deletions sigma-tree/src/chain/ergo_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use sigma_ser::vlq_encode;
#[cfg(feature = "with-serde")]
use std::convert::TryFrom;
use std::io;
#[cfg(feature = "with-serde")]
use thiserror::Error;

/// Box (aka coin, or an unspent output) is a basic concept of a UTXO-based cryptocurrency.
/// In Bitcoin, such an object is associated with some monetary value (arbitrary,
Expand Down Expand Up @@ -143,9 +145,18 @@ impl ErgoBox {
}
}

/// Errors on parsing ErgoBox from JSON
#[cfg(feature = "with-serde")]
#[derive(Error, PartialEq, Eq, Debug, Clone)]
pub enum ErgoBoxFromJsonError {
/// Box id parsed from JSON differs from calculated from box serialized bytes
#[error("Box id parsed from JSON differs from calculated from box serialized bytes")]
InvalidBoxId,
}

#[cfg(feature = "with-serde")]
impl TryFrom<json::ergo_box::ErgoBoxFromJson> for ErgoBox {
type Error = json::ergo_box::ErgoBoxFromJsonError;
type Error = ErgoBoxFromJsonError;
fn try_from(box_json: json::ergo_box::ErgoBoxFromJson) -> Result<Self, Self::Error> {
let box_with_zero_id = ErgoBox {
box_id: BoxId::zero(),
Expand All @@ -165,7 +176,7 @@ impl TryFrom<json::ergo_box::ErgoBoxFromJson> for ErgoBox {
if ergo_box.box_id() == box_json.box_id {
Ok(ergo_box)
} else {
Err(json::ergo_box::ErgoBoxFromJsonError::InvalidBoxId)
Err(ErgoBoxFromJsonError::InvalidBoxId)
}
}
}
Expand Down Expand Up @@ -196,7 +207,7 @@ impl SigmaSerializable for ErgoBox {

/// Contains the same fields as `ErgoBox`, except if transaction id and index,
/// that will be calculated after full transaction formation.
#[derive(PartialEq, Eq, Debug)]
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ErgoBoxCandidate {
/// amount of money associated with the box
pub value: BoxValue,
Expand Down Expand Up @@ -260,6 +271,18 @@ impl SigmaSerializable for ErgoBoxCandidate {
}
}

impl From<ErgoBox> for ErgoBoxCandidate {
fn from(b: ErgoBox) -> Self {
ErgoBoxCandidate {
value: b.value,
ergo_tree: b.ergo_tree,
tokens: b.tokens,
additional_registers: b.additional_registers,
creation_height: b.creation_height,
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
17 changes: 16 additions & 1 deletion sigma-tree/src/chain/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,31 @@ use super::{box_id::BoxId, prover_result::ProverResult};
use serde::{Deserialize, Serialize};

/// Fully signed transaction input
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct Input {
/// id of the box to spent
#[cfg_attr(feature = "with-serde", serde(rename = "boxId"))]
pub box_id: BoxId,
/// proof of spending correctness
#[cfg_attr(feature = "with-serde", serde(rename = "spendingProof"))]
pub spending_proof: ProverResult,
}

impl Input {
/// input with an empty proof
pub fn input_to_sign(&self) -> Input {
Input {
box_id: self.box_id.clone(),
spending_proof: ProverResult {
proof: vec![],
extension: self.spending_proof.extension.clone(),
},
}
}
}

impl SigmaSerializable for Input {
fn sigma_serialize<W: vlq_encode::WriteSigmaVlqExt>(&self, w: &mut W) -> Result<(), io::Error> {
self.box_id.sigma_serialize(w)?;
Expand Down
34 changes: 29 additions & 5 deletions sigma-tree/src/chain/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ pub mod ergo_box {
ErgoTree,
};
use serde::Deserialize;
use thiserror::Error;

#[derive(Deserialize, PartialEq, Eq, Debug, Clone)]
pub struct ErgoBoxFromJson {
Expand Down Expand Up @@ -74,17 +73,33 @@ pub mod ergo_box {
#[serde(rename = "index")]
pub index: u16,
}
}

pub mod transaction {
use crate::chain::{data_input::DataInput, ErgoBox, Input, TxId};
use serde::{Deserialize, Serialize};

#[derive(Error, PartialEq, Eq, Debug, Clone)]
pub enum ErgoBoxFromJsonError {
#[error("Box id parsed from JSON differs from calculated from box serialized bytes")]
InvalidBoxId,
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct TransactionJson {
#[cfg_attr(feature = "with-serde", serde(rename = "id"))]
pub tx_id: TxId,
/// inputs, that will be spent by this transaction.
#[cfg_attr(feature = "with-serde", serde(rename = "inputs"))]
pub inputs: Vec<Input>,
/// inputs, that are not going to be spent by transaction, but will be reachable from inputs
/// scripts. `dataInputs` scripts will not be executed, thus their scripts costs are not
/// included in transaction cost and they do not contain spending proofs.
#[cfg_attr(feature = "with-serde", serde(rename = "dataInputs"))]
pub data_inputs: Vec<DataInput>,
#[cfg_attr(feature = "with-serde", serde(rename = "outputs"))]
pub outputs: Vec<ErgoBox>,
}
}

#[cfg(test)]
mod tests {
use super::super::ergo_box::*;
use super::super::transaction::*;
use super::*;
use proptest::prelude::*;
use register::NonMandatoryRegisters;
Expand All @@ -99,6 +114,15 @@ mod tests {
prop_assert_eq![b, b_parsed];
}

#[test]
fn tx_roundtrip(t in any::<Transaction>()) {
let j = serde_json::to_string(&t)?;
// dbg!(j);
eprintln!("{}", j);
let t_parsed: Transaction = serde_json::from_str(&j)?;
prop_assert_eq![t, t_parsed];
}

}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion sigma-tree/src/chain/prover_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::context_extension::ContextExtension;
use serde::{Deserialize, Serialize};

/// Proof of correctness of tx spending
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct ProverResult {
/// proof that satisfies final sigma proposition
Expand Down
Loading