Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add 8 bit-flags into script type args to control features #10

Merged
merged 1 commit into from
Mar 20, 2024
Merged
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CARGO := @cargo

MOLC := @moleculec
MOLC := moleculec
MOLC_VERSION := 0.7.5

NEXTEST_RUN_ARGS := --no-fail-fast --success-output never --failure-output final
2 changes: 1 addition & 1 deletion prover/src/tests/service.rs
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ fn test_spv_client(
let new_client: packed::SpvClient = service.tip_client().pack();

old_client
.verify_new_client(&new_client, update)
.verify_new_client(&new_client, update, 0)
.map_err(|err| err as i8)
.unwrap();
old_client = new_client;
1 change: 1 addition & 0 deletions verifier/schemas/types.mol
Original file line number Diff line number Diff line change
@@ -53,6 +53,7 @@ struct SpvClient {
struct SpvTypeArgs {
type_id: Hash,
clients_count: byte,
flags: byte,
}

//
3 changes: 3 additions & 0 deletions verifier/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Constants.

pub const FLAG_DISABLE_DIFFICULTY_CHECK: u8 = 0b1000_0000;
1 change: 1 addition & 0 deletions verifier/src/lib.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ extern crate core;
#[macro_use]
mod log;

pub mod constants;
pub mod error;
pub mod types;
pub mod utilities;
1 change: 1 addition & 0 deletions verifier/src/types/conversion/pack.rs
Original file line number Diff line number Diff line change
@@ -104,6 +104,7 @@ impl Pack<packed::SpvTypeArgs> for core::SpvTypeArgs {
packed::SpvTypeArgs::new_builder()
.type_id(self.type_id.pack())
.clients_count(self.clients_count.into())
.flags(self.flags.into())
.build()
}
}
1 change: 1 addition & 0 deletions verifier/src/types/conversion/unpack.rs
Original file line number Diff line number Diff line change
@@ -104,6 +104,7 @@ impl<'r> Unpack<core::SpvTypeArgs> for packed::SpvTypeArgsReader<'r> {
core::SpvTypeArgs {
type_id: self.type_id().unpack(),
clients_count: self.clients_count().into(),
flags: self.flags().into(),
}
}
}
6 changes: 6 additions & 0 deletions verifier/src/types/core.rs
Original file line number Diff line number Diff line change
@@ -84,6 +84,12 @@ pub struct SpvTypeArgs {
///
/// N.B. Exclude the SPV info cell.
pub clients_count: u8,
/// Bit flags to control features.
///
/// From high to low:
/// - Set 0-th bit to true, to disable difficulty checks.
/// - Other bits are reserved.
pub flags: u8,
}

#[cfg(feature = "std")]
19 changes: 14 additions & 5 deletions verifier/src/types/extension/packed.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ use bitcoin::{
use molecule::bytes::Bytes;

use crate::{
constants,
core::result::Result,
error::{BootstrapError, UpdateError, VerifyTxError},
types::{core, packed, prelude::*},
@@ -67,6 +68,7 @@ impl packed::SpvBootstrap {
let header: core::Header =
deserialize(&self.header().raw_data()).map_err(|_| BootstrapError::DecodeHeader)?;
// Verify POW: just trust the input header.
// TODO Check constants::FLAG_DISABLE_DIFFICULTY_CHECK before return errors.
let block_hash = header
.validate_pow(header.target())
.map_err(|_| BootstrapError::Pow)?
@@ -106,6 +108,7 @@ impl packed::SpvClient {
&self,
packed_new_client: &Self,
update: packed::SpvUpdate,
flags: u8,
) -> Result<(), UpdateError> {
let old_client = self.unpack();
let new_client = packed_new_client.unpack();
@@ -146,13 +149,19 @@ impl packed::SpvClient {
expect {expected} but got {actual}"
);
});
return Err(UpdateError::Difficulty);
if flags & constants::FLAG_DISABLE_DIFFICULTY_CHECK == 0 {
return Err(UpdateError::Difficulty);
}
}
// Check POW.
new_tip_block_hash = header
.validate_pow(new_info.1.into())
.map_err(|_| UpdateError::Pow)?
.into();
new_tip_block_hash = if flags & constants::FLAG_DISABLE_DIFFICULTY_CHECK == 0 {
header
.validate_pow(new_info.1.into())
.map_err(|_| UpdateError::Pow)?
} else {
header.block_hash()
}
.into();
// Update the target adjust info.
{
match (new_max_height + 1) % DIFFCHANGE_INTERVAL {
37 changes: 26 additions & 11 deletions verifier/src/types/generated/types.rs
Original file line number Diff line number Diff line change
@@ -3499,6 +3499,7 @@ impl ::core::fmt::Display for SpvTypeArgs {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "type_id", self.type_id())?;
write!(f, ", {}: {}", "clients_count", self.clients_count())?;
write!(f, ", {}: {}", "flags", self.flags())?;
write!(f, " }}")
}
}
@@ -3509,19 +3510,22 @@ impl ::core::default::Default for SpvTypeArgs {
}
}
impl SpvTypeArgs {
const DEFAULT_VALUE: [u8; 33] = [
const DEFAULT_VALUE: [u8; 34] = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
0, 0, 0, 0,
];
pub const TOTAL_SIZE: usize = 33;
pub const FIELD_SIZES: [usize; 2] = [32, 1];
pub const FIELD_COUNT: usize = 2;
pub const TOTAL_SIZE: usize = 34;
pub const FIELD_SIZES: [usize; 3] = [32, 1, 1];
pub const FIELD_COUNT: usize = 3;
pub fn type_id(&self) -> Hash {
Hash::new_unchecked(self.0.slice(0..32))
}
pub fn clients_count(&self) -> Byte {
Byte::new_unchecked(self.0.slice(32..33))
}
pub fn flags(&self) -> Byte {
Byte::new_unchecked(self.0.slice(33..34))
}
pub fn as_reader<'r>(&'r self) -> SpvTypeArgsReader<'r> {
SpvTypeArgsReader::new_unchecked(self.as_slice())
}
@@ -3551,6 +3555,7 @@ impl molecule::prelude::Entity for SpvTypeArgs {
Self::new_builder()
.type_id(self.type_id())
.clients_count(self.clients_count())
.flags(self.flags())
}
}
#[derive(Clone, Copy)]
@@ -3574,19 +3579,23 @@ impl<'r> ::core::fmt::Display for SpvTypeArgsReader<'r> {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "type_id", self.type_id())?;
write!(f, ", {}: {}", "clients_count", self.clients_count())?;
write!(f, ", {}: {}", "flags", self.flags())?;
write!(f, " }}")
}
}
impl<'r> SpvTypeArgsReader<'r> {
pub const TOTAL_SIZE: usize = 33;
pub const FIELD_SIZES: [usize; 2] = [32, 1];
pub const FIELD_COUNT: usize = 2;
pub const TOTAL_SIZE: usize = 34;
pub const FIELD_SIZES: [usize; 3] = [32, 1, 1];
pub const FIELD_COUNT: usize = 3;
pub fn type_id(&self) -> HashReader<'r> {
HashReader::new_unchecked(&self.as_slice()[0..32])
}
pub fn clients_count(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[32..33])
}
pub fn flags(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[33..34])
}
}
impl<'r> molecule::prelude::Reader<'r> for SpvTypeArgsReader<'r> {
type Entity = SpvTypeArgs;
@@ -3613,11 +3622,12 @@ impl<'r> molecule::prelude::Reader<'r> for SpvTypeArgsReader<'r> {
pub struct SpvTypeArgsBuilder {
pub(crate) type_id: Hash,
pub(crate) clients_count: Byte,
pub(crate) flags: Byte,
}
impl SpvTypeArgsBuilder {
pub const TOTAL_SIZE: usize = 33;
pub const FIELD_SIZES: [usize; 2] = [32, 1];
pub const FIELD_COUNT: usize = 2;
pub const TOTAL_SIZE: usize = 34;
pub const FIELD_SIZES: [usize; 3] = [32, 1, 1];
pub const FIELD_COUNT: usize = 3;
pub fn type_id(mut self, v: Hash) -> Self {
self.type_id = v;
self
@@ -3626,6 +3636,10 @@ impl SpvTypeArgsBuilder {
self.clients_count = v;
self
}
pub fn flags(mut self, v: Byte) -> Self {
self.flags = v;
self
}
}
impl molecule::prelude::Builder for SpvTypeArgsBuilder {
type Entity = SpvTypeArgs;
@@ -3636,6 +3650,7 @@ impl molecule::prelude::Builder for SpvTypeArgsBuilder {
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
writer.write_all(self.type_id.as_slice())?;
writer.write_all(self.clients_count.as_slice())?;
writer.write_all(self.flags.as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {