Skip to content

Commit

Permalink
complete state arithmetics
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Dec 11, 2024
1 parent f089503 commit 9a59f52
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 25 deletions.
27 changes: 22 additions & 5 deletions api/src/adaptors/alu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@
// or implied. See the License for the specific language governing permissions and limitations under
// the License.

use std::iter;
use aluvm::LibSite;
use amplify::confinement::ConfinedBlob;
use strict_types::{SemId, StrictDumb, StrictVal, TypeSystem};
use ultrasonic::{StateData, StateValue};

use crate::api::TOTAL_BYTES;
use crate::{ApiVm, StateAdaptor, StateArithm, StateAtom, StateName, StateReader, StructData, VmType, LIB_NAME_SONIC};
use crate::{ApiVm, StateAdaptor, StateArithm, StateAtom, StateCalc, StateName, StateReader, UncountableState, VmType, LIB_NAME_SONIC};

impl ApiVm for aluvm::Vm {
type Arithm = AluVMArithm;
Expand Down Expand Up @@ -99,11 +100,27 @@ impl StrictDumb for AluVMArithm {
}

impl StateArithm for AluVMArithm {
fn measure(&self, state: StructData) -> Option<u8> { todo!() }
type Calc = ();

fn accumulate(&mut self, state: StructData) -> Option<()> { todo!() }
fn measure(&self, state: StateValue, target: StateValue) -> Option<i8> {
todo!()
}

fn calculator(&self) -> Self::Calc {
todo!()
}
}

fn lessen(&mut self, state: StructData) -> Option<()> { todo!() }
impl StateCalc for () {
fn accumulate(&mut self, state: StateValue) -> Result<(), UncountableState> {
Err(UncountableState)
}

fn diff(&self) -> Option<StructData> { todo!() }
fn lessen(&mut self, state: StateValue) -> Result<(), UncountableState> {
Err(UncountableState)
}

fn diff(self) -> Result<impl Iterator<Item=StateValue>, UncountableState> {
Err::<iter::Empty<_>, _>(UncountableState)
}
}
85 changes: 77 additions & 8 deletions api/src/adaptors/embedded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ use strict_encoding::{StreamReader, StrictDecode, StrictEncode};
use strict_types::typify::TypedVal;
use strict_types::value::StrictNum;
use strict_types::{SemId, StrictVal, TypeSystem};
use ultrasonic::{StateData, StateValue};
use ultrasonic::{fe256, StateData, StateValue};

use crate::api::{TOTAL_BYTES, USED_FIEL_BYTES};
use crate::{
ApiVm, StateAdaptor, StateArithm, StateAtom, StateName, StateReader, StateTy, StructData, VmType, LIB_NAME_SONIC,
};
use crate::{ApiVm, StateAdaptor, StateArithm, StateAtom, StateCalc, StateName, StateReader, StateTy, UncountableState, VmType, LIB_NAME_SONIC};

#[derive(Clone, Debug)]
pub struct EmbeddedProc;
Expand Down Expand Up @@ -198,11 +196,82 @@ pub enum EmbeddedArithm {
}

impl StateArithm for EmbeddedArithm {
fn measure(&self, state: StructData) -> Option<u8> { todo!() }
type Calc = EmbeddedCalc;

fn accumulate(&mut self, state: StructData) -> Option<()> { todo!() }
fn measure(&self, state: StateValue, target: StateValue) -> Option<i8> {
let res = match (state, target) {
(StateValue::Single { first: val }, StateValue::Single { first: tgt }) if val.to_u256() == tgt.to_u256() => return Some(0),
(StateValue::Single { first: val }, StateValue::Single { first: tgt }) if val.to_u256() < tgt.to_u256() => {
(tgt.to_u256() - val.to_u256()) / tgt.to_u256()
}
(StateValue::Single { first: val }, StateValue::Single { first: tgt }) if val.to_u256() > tgt.to_u256() => {
(val.to_u256() - tgt.to_u256()) / tgt.to_u256()
}
_ => return None,
};
if res > u256::from(u64::MAX) {
Some(i8::MAX)
} else {
Some(res.low_u64().ilog2() as i8)
}
}

fn calculator(&self) -> Self::Calc {
match self {
EmbeddedArithm::NonFungible => EmbeddedCalc::NonFungible(empty!()),
EmbeddedArithm::Fungible => EmbeddedCalc::Fungible(StateValue::None),
}
}
}

#[derive(Clone, Eq, PartialEq, Debug)]
pub enum EmbeddedCalc {
NonFungible(Vec<StateValue>),
Fungible(StateValue),
}

impl StateCalc for EmbeddedCalc {
fn accumulate(&mut self, state: StateValue) -> Result<(), UncountableState> { match self {
EmbeddedCalc::NonFungible(states) => {
states.push(state);
Ok(())
}
EmbeddedCalc::Fungible(value) => {
match (state, value) {
(StateValue::Single { first: add }, StateValue::Single { first: val }) => {
*val = fe256::from(val.to_u256() + add.to_u256());
Ok(())
}
_ => Err(UncountableState)
}
}
} }

fn lessen(&mut self, state: StructData) -> Option<()> { todo!() }
fn lessen(&mut self, state: StateValue) -> Result<(), UncountableState> { match self {
EmbeddedCalc::NonFungible(states) => {
if let Some(pos) = states.iter().position(|s| *s == state) {
states.remove(pos);
Ok(())
} else {
Err(UncountableState)
}
}
EmbeddedCalc::Fungible(value) => {
match (state, value) {
(StateValue::Single { first: dec }, StateValue::Single { first: val }) if dec.to_u256() > val.to_u256() => Err(UncountableState),
(StateValue::Single { first: dec }, StateValue::Single { first: val }) => {
*val = fe256::from(val.to_u256() - dec.to_u256());
Ok(())
},
_ => Err(UncountableState),
}
}
} }

fn diff(&self) -> Option<StructData> { todo!() }
fn diff(self) -> Result<impl Iterator<Item = StateValue>, UncountableState> {
Ok(match self {
EmbeddedCalc::NonFungible(items) => items,
EmbeddedCalc::Fungible(value) => vec![value]
}.into_iter())
}
}
34 changes: 23 additions & 11 deletions api/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use strict_types::{SemId, StrictDecode, StrictDumb, StrictEncode, StrictVal, Typ
use ultrasonic::{CallId, CodexId, Identity, StateData, StateValue};

use crate::embedded::EmbeddedProc;
use crate::{StateAtom, StructData, VmType, LIB_NAME_SONIC};
use crate::{StateAtom, VmType, LIB_NAME_SONIC};

pub(super) const USED_FIEL_BYTES: usize = u256::BYTES as usize - 2;
pub(super) const TOTAL_BYTES: usize = USED_FIEL_BYTES * 3;
Expand Down Expand Up @@ -410,6 +410,7 @@ impl<Vm: ApiVm> DestructibleApi<Vm> {
pub fn build(&self, value: StrictVal, sys: &TypeSystem) -> StateValue {
self.adaptor.build_state(self.sem_id, value, sys)
}
pub fn arithmetics(&self) -> &Vm::Arithm { &self.arithmetics }
}

#[cfg(not(feature = "serde"))]
Expand Down Expand Up @@ -461,22 +462,33 @@ pub trait StateAdaptor: Clone + Ord + Debug + StrictDumb + StrictEncode + Strict
}
}

// TODO: Use Result's instead of Option
pub trait StateArithm: Clone + Debug + StrictDumb + StrictEncode + StrictDecode + Serde {
/// Procedure which converts [`StructData`] corresponding to this type into a weight in range
/// `0..256` representing how much this specific state fulfills certain state requirement.
/// Type that performs calculations on the state
type Calc: StateCalc;

/// Procedure which converts [`StateValue`] corresponding to this type into a weight in range
/// `-126..127` representing how much this specific state fulfills certain state requirement.
///
/// This is used in selecting state required to fulfill input for a provided contract
/// [`Request`].
fn measure(&self, state: StructData) -> Option<u8>;
fn measure(&self, state: StateValue, target: StateValue) -> Option<i8>;

/// Returns a calculator object used to perform calculations on the state.
fn calculator(&self) -> Self::Calc;
}

#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display, Error)]
#[display("state can't be computed")]
pub struct UncountableState;

/// Procedure which is called on [`StateArithm`] to accumulate an input state.
fn accumulate(&mut self, state: StructData) -> Option<()>;
pub trait StateCalc {
/// Procedure which is called on [`StateCalc`] to accumulate an input state.
fn accumulate(&mut self, state: StateValue) -> Result<(), UncountableState>;

/// Procedure which is called on [`StateArithm`] to lessen an output state.
fn lessen(&mut self, state: StructData) -> Option<()>;
/// Procedure which is called on [`StateCalc`] to lessen an output state.
fn lessen(&mut self, state: StateValue) -> Result<(), UncountableState>;

/// Procedure which is called on [`StateArithm`] to compute the difference between an input
/// Procedure which is called on [`StateCalc`] to compute the difference between an input
/// state and output state.
fn diff(&self) -> Option<StructData>;
fn diff(self) -> Result<impl Iterator<Item = StateValue>, UncountableState>;
}
2 changes: 1 addition & 1 deletion api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ mod util;
pub use adaptors::{alu, embedded};
pub use api::{
Api, ApiId, ApiInner, ApiVm, AppendApi, DestructibleApi, MethodName, StateAdaptor, StateArithm, StateName,
StateReader,
StateReader, StateCalc, UncountableState
};
pub use articles::{Articles, MergeError};
pub use builders::{Builder, BuilderRef, CoreParams, IssueParams, NamedState, OpBuilder, OpBuilderRef};
Expand Down

0 comments on commit 9a59f52

Please sign in to comment.