Skip to content

Commit

Permalink
RGB schema: feature flags versioning. Closes #72
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Oct 1, 2020
1 parent 4169dc4 commit 903197d
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/bp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use bitcoin::hashes::{sha256d, Hash};

#[macro_use]
pub mod tagged256;
#[allow(unused_variables)]
pub mod bip32;
pub mod blind;
pub mod chain;
Expand Down
65 changes: 43 additions & 22 deletions src/common/features.rs → src/common/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// If not, see <https://opensource.org/licenses/MIT>.

use std::cmp::max;
use std::fmt::{self, Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::io;
use std::ops::{BitAnd, BitOr, BitXor};
Expand All @@ -34,9 +35,9 @@ pub struct FlagRef<'a> {

/// Structure holding a given set of features
#[derive(Clone)]
pub struct Features(Vec<u8>);
pub struct FlagVec(Vec<u8>);

impl BitOr for Features {
impl BitOr for FlagVec {
type Output = Self;
fn bitor(self, mut rhs: Self) -> Self::Output {
let mut lhs = self.shrunk();
Expand All @@ -51,7 +52,7 @@ impl BitOr for Features {
}
}

impl BitAnd for Features {
impl BitAnd for FlagVec {
type Output = Self;
fn bitand(self, mut rhs: Self) -> Self::Output {
let mut lhs = self.shrunk();
Expand All @@ -66,7 +67,7 @@ impl BitAnd for Features {
}
}

impl BitXor for Features {
impl BitXor for FlagVec {
type Output = Self;
fn bitxor(self, mut rhs: Self) -> Self::Output {
let mut lhs = self.shrunk();
Expand All @@ -81,42 +82,62 @@ impl BitXor for Features {
}
}

impl Default for Features {
impl Default for FlagVec {
fn default() -> Self {
Features::new()
FlagVec::new()
}
}

impl PartialEq for Features {
impl PartialEq for FlagVec {
fn eq(&self, other: &Self) -> bool {
self.shrunk().0 == other.shrunk().0
}
}

impl Eq for Features {}
impl Eq for FlagVec {}

impl Hash for Features {
impl Hash for FlagVec {
fn hash<H: Hasher>(&self, state: &mut H) {
self.shrunk().0.hash(state)
}
}

impl StrictEncode for Features {
impl Debug for FlagVec {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_str("flags:")?;
for b in 0..self.capacity() {
write!(f, "{}", if self.is_set(b) { 1 } else { 0 })?;
}
Ok(())
}
}

impl Display for FlagVec {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let cap = self.shrunk().capacity();
for b in 0..cap {
write!(f, "{}", if self.is_set(b) { 1 } else { 0 })?;
}
Ok(())
}
}

impl StrictEncode for FlagVec {
fn strict_encode<E: io::Write>(&self, e: E) -> Result<usize, Self::Error> {
self.shrunk().0.strict_encode(e)
}
}

impl StrictDecode for Features {
impl StrictDecode for FlagVec {
fn strict_decode<D: io::Read>(d: D) -> Result<Self, Self::Error> {
Ok(Self(StrictDecode::strict_decode(d)?))
}
}

impl Features {
impl FlagVec {
/// Constructs a features vector of zero feature flag set
pub fn new() -> Features {
Features(vec![])
pub fn new() -> FlagVec {
FlagVec(vec![])
}

/// Returns a shrunk copy of the self
Expand All @@ -134,15 +155,15 @@ impl Features {

/// Creates iterator over known set of the features
#[inline]
pub fn known_iter(&self, mut known: Features) -> FilteredIter {
pub fn known_iter(&self, mut known: FlagVec) -> FilteredIter {
known.enlarge(self.capacity());
FilteredIter::new(&self, known)
}

/// Creates iterator over unknown set of the features, i.e. features that
/// **do not** match flags set in `known` parameter
#[inline]
pub fn unknown_iter(&self, mut known: Features) -> FilteredIter {
pub fn unknown_iter(&self, mut known: FlagVec) -> FilteredIter {
known.enlarge(self.capacity());
for byte in 1..self.capacity() {
known.0[byte as usize] = !known.0[byte as usize];
Expand Down Expand Up @@ -182,7 +203,7 @@ impl Features {
pub fn shrink(&mut self) -> bool {
let capacity = self.capacity();
let mut top = 1;
while !self.is_set(capacity - top) && top < capacity {
while top < capacity && !self.is_set(capacity - top) {
top += 1;
}
let used = ((top + 1) / 8) as usize;
Expand Down Expand Up @@ -259,7 +280,7 @@ impl Features {
#[derive(Clone, PartialEq, Eq)]
pub struct AllSet<'a> {
/// Reference to features object we iterate
features: &'a Features,
features: &'a FlagVec,

/// Offset of the last feature flag
offset: FlagNo,
Expand All @@ -268,7 +289,7 @@ pub struct AllSet<'a> {
impl<'a> AllSet<'a> {
/// Constructs an iterator over a given set of feature flags
#[inline]
pub fn new(features: &'a Features) -> Self {
pub fn new(features: &'a FlagVec) -> Self {
Self {
features,
offset: 0,
Expand All @@ -295,10 +316,10 @@ impl Iterator for AllSet<'_> {
#[derive(Clone, PartialEq, Eq)]
pub struct FilteredIter<'a> {
/// Reference to features object we iterate
features: &'a Features,
features: &'a FlagVec,

/// Parameter defining a set of features which are known
filter: Features,
filter: FlagVec,

/// Offset of the last feature flag
offset: FlagNo,
Expand All @@ -308,7 +329,7 @@ impl<'a> FilteredIter<'a> {
/// Constructs an iterator over a given set of features with some filter for
/// feature flags
#[inline]
pub fn new(features: &'a Features, filter: Features) -> Self {
pub fn new(features: &'a FlagVec, filter: FlagVec) -> Self {
Self {
features,
filter,
Expand Down
3 changes: 1 addition & 2 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@
mod bipolar;
pub mod data_format;
pub mod features;
pub mod feature;
pub mod internet;
#[cfg(feature = "daemons")]
pub mod service;

pub use bipolar::Bipolar;
pub use features::Features;
#[cfg(feature = "daemons")]
pub use service::{Service, TryService};
2 changes: 1 addition & 1 deletion src/rgb/contract/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ mod strict_encoding {
}
let chain_data = Vec::<u8>::strict_decode(&mut d)?;
let chain = strict_decode(&chain_data)?;
for n in 1..chain_params_no {
for _ in 1..chain_params_no {
// Ignoring the rest of chain parameters
let _ = Vec::<u8>::strict_decode(&mut d)?;
}
Expand Down
17 changes: 10 additions & 7 deletions src/rgb/schema/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use super::{
TransitionSchema,
};
use crate::client_side_validation::{commit_strategy, CommitEncodeWithStrategy, ConsensusCommit};
use crate::feature;
use crate::rgb::schema::ValenciesType;

// Here we can use usize since encoding/decoding makes sure that it's u16
Expand All @@ -47,8 +48,7 @@ tagged_hash!(

#[derive(Clone, PartialEq, Debug)]
pub struct Schema {
// TODO: (new) add versioning/features
// pub rgb_features: FeatureFlags,
pub rgb_features: feature::FlagVec,
// TODO: (new) add superschema reference
// pub family_schema_id: SchemaId,
pub field_types: BTreeMap<FieldType, DataFormat>,
Expand Down Expand Up @@ -93,6 +93,7 @@ mod strict_encoding {

fn strict_encode<E: io::Write>(&self, mut e: E) -> Result<usize, Self::Error> {
Ok(strict_encode_list!(e;
self.rgb_features,
self.field_types,
self.assignment_types,
self.valencies_types,
Expand All @@ -110,6 +111,7 @@ mod strict_encoding {

fn strict_decode<D: io::Read>(mut d: D) -> Result<Self, Self::Error> {
let me = Self {
rgb_features: feature::FlagVec::strict_decode(&mut d)?,
field_types: BTreeMap::strict_decode(&mut d)?,
assignment_types: BTreeMap::strict_decode(&mut d)?,
valencies_types: BTreeSet::strict_decode(&mut d)?,
Expand Down Expand Up @@ -578,6 +580,7 @@ pub(crate) mod test {
const EXTENSION_DECENTRALIZED_ISSUE: usize = 0;

Schema {
rgb_features: feature::FlagVec::default(),
field_types: bmap! {
FIELD_TICKER => DataFormat::String(16),
FIELD_NAME => DataFormat::String(256),
Expand Down Expand Up @@ -698,11 +701,11 @@ pub(crate) mod test {
let schema = schema();
let encoded = strict_encode(&schema).unwrap();
let encoded_standard: Vec<u8> = vec![
10, 0, 0, 0, 4, 16, 0, 1, 0, 4, 0, 1, 2, 0, 4, 0, 4, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 255, 255, 4, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255,
255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255,
255, 255, 255, 255, 255, 6, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0,
7, 0, 5, 255, 255, 8, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255,
0, 0, 10, 0, 0, 0, 4, 16, 0, 1, 0, 4, 0, 1, 2, 0, 4, 0, 4, 3, 0, 0, 8, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 4, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
255, 255, 255, 255, 255, 255, 6, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0,
0, 7, 0, 5, 255, 255, 8, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255,
255, 255, 16, 0, 4, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 255, 2, 1, 0, 1, 0, 8, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 255, 1, 2, 0, 0, 1, 0, 0,
255, 3, 1, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
Expand Down
1 change: 0 additions & 1 deletion src/rgb/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ impl<'validator, R: TxResolver> Validator<'validator, R> {
fn validate_graph_node(&mut self, node: &'validator dyn Node, anchor: &'validator Anchor) {
let txid = anchor.txid;
let node_id = node.node_id();
let node_type = node.node_type();

// Check that the anchor is committed into a transaction spending all of
// the transition inputs.
Expand Down

0 comments on commit 903197d

Please sign in to comment.