Skip to content
Open
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 src/constructive/bitcoiny/airly.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
| VM Type | Encoding | Scope | Indexing | Nonce | Gas Price/Limit | Calldata | Signature | Error-handling |
|:--------|:--------------------------------|:-----------|:----------------|-----------|:----------------|:-------------|:---------------|:---------------|
| Cube | Airly Payload Encoding (APE) | Bit-level | Rank-based | - | Negligible | Non-prefixed | BLS-aggregated | Assertions |
| zkEVM | Recursive-length prefix (RLP) | Byte-level | Registery-based | Present | Present | Prefixed | ZK-aggregated | Failures |
| zkEVM | Recursive-length prefix (RLP) | Byte-level | Registry-based | Present | Present | Prefixed | ZK-aggregated | Failures |
| EVM | Recursive-length prefix (RLP) | Byte-level | - | Present | Present | Prefixed | 65 bytes | Failures |

`Airly Compression` is composed of 9 key techniques:
Expand All @@ -31,7 +31,7 @@ Cube indexes `Accounts` and `Contracts` based on how frequently they transact, r

This rank-based indexing system is cached and managed at the memory level, ensuring that frequently used contracts—such as AMM pools or Tether—consume only ~1 byte, compared to zkEVM’s 4 bytes and EVM’s 20 bytes.

See [Registery Manager](https://github.com/cube-btc/cube/tree/main/src/inscriptive/registery).
See [Registry Manager](https://github.com/cube-btc/cube/tree/main/src/inscriptive/registry).

#### 4. Non-prefixed Calldata
Cube maps calldata items directly to pre-defined types with known lengths, eliminating the prefix overhead for calldata. In contrast, the EVM requires calldata to be prefixed with an `RLP` encoding, adding 1-2 bytes overhead.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::constructive::core_types::entities::contract::contract::Contract;
use crate::constructive::core_types::valtypes::maybe_common::maybe_common::maybe_common::MaybeCommon;
use crate::constructive::core_types::valtypes::val::long_val::long_val::LongVal;
use crate::constructive::core_types::valtypes::val::short_val::short_val::ShortVal;
use crate::inscriptive::registery::registery::REGISTERY;
use crate::inscriptive::registry::registry::REGISTRY;

use bit_vec::BitVec;

Expand All @@ -23,12 +23,12 @@ impl CalldataElement {
/// # Arguments
/// * `bit_stream` - The APE bitstream.
/// * `element_type` - The type of the `CallElement`.
/// * `registery_manager` - The `Registery Manager`.
/// * `registry_manager` - The `Registry Manager`.
/// * `decode_rank_as_longval` - Whether to decode the rank value as a `LongVal` or a `ShortVal`.
pub async fn decode_ape<'a>(
bit_stream: &mut bit_vec::Iter<'_>,
element_type: CalldataElementType,
registery: &REGISTERY,
registry: &REGISTRY,
decode_rank_as_longval: bool,
) -> Result<Self, CalldataElementAPEDecodeError> {
// Match on the calldata element type.
Expand Down Expand Up @@ -142,7 +142,7 @@ impl CalldataElement {
// Decode the `Account`.
CalldataElementType::Account => {
// Decode the `Account`.
let account = Account::decode_ape(bit_stream, &registery, decode_rank_as_longval)
let account = Account::decode_ape(bit_stream, &registry, decode_rank_as_longval)
.await
.map_err(|e| {
CalldataElementAPEDecodeError::Account(
Expand All @@ -160,7 +160,7 @@ impl CalldataElement {
// Decode the `Contract`.
CalldataElementType::Contract => {
// Decode the `Contract`.
let contract = Contract::decode_ape(bit_stream, &registery, decode_rank_as_longval)
let contract = Contract::decode_ape(bit_stream, &registry, decode_rank_as_longval)
.await
.map_err(|e| {
CalldataElementAPEDecodeError::Contract(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::constructive::core_types::calldata::calldata_elements::calldata_eleme
use crate::constructive::core_types::valtypes::maybe_common::maybe_common::maybe_common::MaybeCommon;
use crate::constructive::core_types::valtypes::val::long_val::long_val::LongVal;
use crate::constructive::core_types::valtypes::val::short_val::short_val::ShortVal;
use crate::inscriptive::registery::registery::REGISTERY;
use crate::inscriptive::registry::registry::REGISTRY;
use bit_vec::BitVec;

impl CalldataElement {
Expand All @@ -14,13 +14,13 @@ impl CalldataElement {
///
/// # Arguments
/// * `&self` - The `CallElement` to encode.
/// * `registery_manager` - The guarded `RegisteryManager` to get the `Account`'s rank value.
/// * `registry_manager` - The guarded `RegistryManager` to get the `Account`'s rank value.
/// * `encode_rank_as_longval` - Whether to encode the rank value as a `LongVal` or a `ShortVal`.
///
/// # Returns
pub async fn encode_ape(
&self,
registery: &REGISTERY,
registry: &REGISTRY,
encode_account_rank_as_longval: bool,
encode_contract_rank_as_longval: bool,
) -> Result<BitVec, CalldataElementAPEEncodeError> {
Expand Down Expand Up @@ -82,7 +82,7 @@ impl CalldataElement {
CalldataElement::Account(account) => {
// Encode the `Account`.
let bits = account
.encode_ape(registery, encode_account_rank_as_longval)
.encode_ape(registry, encode_account_rank_as_longval)
.await
.map_err(|e| CalldataElementAPEEncodeError::AccountAPEEncodeError(e))?;

Expand All @@ -92,7 +92,7 @@ impl CalldataElement {
CalldataElement::Contract(contract) => {
// Encode the `Contract`.
let bits = contract
.encode_ape(registery, encode_contract_rank_as_longval)
.encode_ape(registry, encode_contract_rank_as_longval)
.await
.map_err(|e| CalldataElementAPEEncodeError::ContractAPEEncodeError(e))?;

Expand Down
26 changes: 13 additions & 13 deletions src/constructive/core_types/entities/account/account/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::constructive::core_types::entities::account::account::{
registered_account::registered_account::RegisteredAccount,
unregistered_account::unregistered_account::UnregisteredAccount,
};
use crate::inscriptive::registery::registery::REGISTERY;
use crate::inscriptive::registry::registry::REGISTRY;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};

Expand All @@ -17,26 +17,26 @@ pub enum Account {
}

impl Account {
/// Returns the `Account` for the given account key from the `Registery`.
pub async fn account_from_registery(
/// Returns the `Account` for the given account key from the `Registry`.
pub async fn account_from_registry(
account_key: [u8; 32],
registery: &REGISTERY,
registry: &REGISTRY,
) -> Account {
// 1 Retrieve the account info if it is registered.
let account_info = {
// 1.1 Lock the registery.
let _registery = registery.lock().await;
// 1.1 Lock the registry.
let _registry = registry.lock().await;

// 1.2 Get account info by account key.
_registery.get_account_info_by_account_key(account_key)
_registry.get_account_info_by_account_key(account_key)
};

// 2 Match on whether the account is registered or not.
match account_info {
// 2.a The account is registered.
Some((_, _, registery_index, _)) => {
Some((_, _, registry_index, _)) => {
// 2.a.1 Construct the `RegisteredAccount`.
let registered_account = RegisteredAccount::new(account_key, registery_index);
let registered_account = RegisteredAccount::new(account_key, registry_index);

// 2.a.2 Construct and return the `Account`.
Self::RegisteredAccount(registered_account)
Expand All @@ -54,9 +54,9 @@ impl Account {
}

/// Creates a new registered account.
pub fn new_registered_account(account_key: [u8; 32], registery_index: u64) -> Self {
pub fn new_registered_account(account_key: [u8; 32], registry_index: u64) -> Self {
// 1 Construct the registered account.
let registered_account = RegisteredAccount::new(account_key, registery_index);
let registered_account = RegisteredAccount::new(account_key, registry_index);

// 2 Return the registered account.
Self::RegisteredAccount(registered_account)
Expand Down Expand Up @@ -97,8 +97,8 @@ impl Account {
Value::String(hex::encode(registered_account.account_key)),
);
obj.insert(
"registery_index".to_string(),
Value::Number(registered_account.registery_index.into()),
"registry_index".to_string(),
Value::Number(registered_account.registry_index.into()),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ use crate::constructive::core_types::entities::account::account::ext::codec::ape
use crate::constructive::core_types::entities::account::account::unregistered_account::unregistered_account::UnregisteredAccount;
use crate::constructive::core_types::valtypes::val::long_val::long_val::LongVal;
use crate::constructive::core_types::valtypes::val::short_val::short_val::ShortVal;
use crate::inscriptive::registery::registery::REGISTERY;
use crate::inscriptive::registry::registry::REGISTRY;
use bit_vec::BitVec;

impl Account {
/// Decodes an `Account` as an Airly Payload Encoding (APE) bit vector.
pub async fn decode_ape<'a>(
bit_stream: &mut bit_vec::Iter<'a>,
registery: &REGISTERY,
registry: &REGISTRY,
decode_rank_as_longval: bool,
) -> Result<Account, AccountAPEDecodeError> {
// 1 Decode the rank value from the APE bitstream.
Expand Down Expand Up @@ -57,13 +57,13 @@ impl Account {

// 2.b The `Account` is registered.
_ => {
// 2.b.1 Retrieve the `Account` from the `Registery Manager` by its rank.
// 2.b.1 Retrieve the `Account` from the `Registry Manager` by its rank.
let account = {
// 2.b.1.1 Lock the `Registery Manager`.
let _registery = registery.lock().await;
// 2.b.1.1 Lock the `Registry Manager`.
let _registry = registry.lock().await;

// 2.b.1.2 Retrieve the `Account` from the `Registery Manager` by its rank.
_registery
// 2.b.1.2 Retrieve the `Account` from the `Registry Manager` by its rank.
_registry
.get_account_by_rank(rank)
.ok_or(AccountAPEDecodeError::FailedToLocateAccountGivenRank(rank))?
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use crate::constructive::core_types::entities::account::account::account::Accoun
use crate::constructive::core_types::entities::account::account::ext::codec::ape::encode::error::encode_error::AccountAPEEncodeError;
use crate::constructive::core_types::valtypes::val::long_val::long_val::LongVal;
use crate::constructive::core_types::valtypes::val::short_val::short_val::ShortVal;
use crate::inscriptive::registery::registery::REGISTERY;
use crate::inscriptive::registry::registry::REGISTRY;
use bit_vec::BitVec;

impl Account {
/// Encodes an `Account` as an Airly Payload Encoding (APE) bit vector.
pub async fn encode_ape(
&self,
registery: &REGISTERY,
registry: &REGISTRY,
encode_rank_as_longval: bool,
) -> Result<BitVec, AccountAPEEncodeError> {
// 1 Initialize the APE bit vector.
Expand All @@ -27,14 +27,14 @@ impl Account {

// 2.a.1 Get the rank value.
let rank = {
// 2.a.1.1 Lock the `Registery`.
let _registery = registery.lock().await;
// 2.a.1.1 Lock the `Registry`.
let _registry = registry.lock().await;

// 2.a.1.2 Get the `Account`'s rank value from the `Registery`.
_registery
// 2.a.1.2 Get the `Account`'s rank value from the `Registry`.
_registry
.get_rank_by_account_key(self.account_key())
.ok_or(
AccountAPEEncodeError::UnableToRetrieveRankValueFromRegistery(
AccountAPEEncodeError::UnableToRetrieveRankValueFromRegistry(
self.account_key(),
),
)?
Expand Down Expand Up @@ -66,7 +66,7 @@ impl Account {
false => {
//
// When the `Account` is not registered, we encode a zero rank value as a `LongVal` or a `ShortVal` to indicate that the `Account` is unregistered.
// and right afterwards we encode the full 256 public key bits of the `Account`'s public key to register it with the `RegisteryManager`.
// and right afterwards we encode the full 256 public key bits of the `Account`'s public key to register it with the `RegistryManager`.
//

// 2.b.1 Match on whether to encode the zero rank value as a `LongVal` or a `ShortVal`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ type AccountKey = [u8; 32];
/// Enum to represent errors that can occur when encoding an `Account` as a bit vector.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum AccountAPEEncodeError {
UnableToRetrieveRankValueFromRegistery(AccountKey),
UnableToRetrieveRankValueFromRegistry(AccountKey),
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,26 @@ impl Account {
.try_into()
.map_err(|_| AccountSBEDecodeError::RegisteredAccountSBEAccountKeyBytesConversionError)?;

// 4.b.3 Ensure the payload holds the 8-byte little-endian registery index after the key.
// 4.b.3 Ensure the payload holds the 8-byte little-endian registry index after the key.
if payload.len() < 32 + 8 {
return Err(
AccountSBEDecodeError::RegisteredAccountSBEInsufficientBytesForRegisteryIndex {
AccountSBEDecodeError::RegisteredAccountSBEInsufficientBytesForRegistryIndex {
got_total: payload.len(),
},
);
}

// 4.b.4 Decode the registery index.
let registery_index = u64::from_le_bytes(
// 4.b.4 Decode the registry index.
let registry_index = u64::from_le_bytes(
payload[32..40]
.try_into()
.map_err(|_| AccountSBEDecodeError::RegisteredAccountSBERegisteryIndexBytesConversionError)?,
.map_err(|_| AccountSBEDecodeError::RegisteredAccountSBERegistryIndexBytesConversionError)?,
);

// 4.b.5 Ensure no trailing bytes after the registery index.
// 4.b.5 Ensure no trailing bytes after the registry index.
if payload.len() != 32 + 8 {
return Err(
AccountSBEDecodeError::RegisteredAccountSBETrailingBytesAfterRegisteryIndex {
AccountSBEDecodeError::RegisteredAccountSBETrailingBytesAfterRegistryIndex {
trailing: payload.len() - (32 + 8),
},
);
Expand All @@ -95,7 +95,7 @@ impl Account {
// 4.b.6 Construct and return the registered `Account`.
Ok(Account::RegisteredAccount(RegisteredAccount::new(
account_key,
registery_index,
registry_index,
)))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ pub enum AccountSBEDecodeError {
/// Bytes remained after the 32-byte account key in an `UnregisteredAccount` payload.
UnregisteredAccountSBETrailingBytesAfterAccountKey { trailing: usize },

// RegisteredAccount — Schnorr account key (32 bytes) + registery index (8 bytes).
// RegisteredAccount — Schnorr account key (32 bytes) + registry index (8 bytes).
/// The payload after `0x01` ended before the 32-byte Schnorr account key.
RegisteredAccountSBEInsufficientBytesForAccountKey { got_total: usize },
/// Failed to assemble the 32-byte Schnorr account key from the SBE payload.
RegisteredAccountSBEAccountKeyBytesConversionError,
/// The payload after the 32-byte account key ended before the 8-byte little-endian registery index.
RegisteredAccountSBEInsufficientBytesForRegisteryIndex { got_total: usize },
/// Failed to assemble the 8-byte registery index from the SBE payload.
RegisteredAccountSBERegisteryIndexBytesConversionError,
/// Bytes remained after the account key and registery index in a `RegisteredAccount` payload.
RegisteredAccountSBETrailingBytesAfterRegisteryIndex { trailing: usize },
/// The payload after the 32-byte account key ended before the 8-byte little-endian registry index.
RegisteredAccountSBEInsufficientBytesForRegistryIndex { got_total: usize },
/// Failed to assemble the 8-byte registry index from the SBE payload.
RegisteredAccountSBERegistryIndexBytesConversionError,
/// Bytes remained after the account key and registry index in a `RegisteredAccount` payload.
RegisteredAccountSBETrailingBytesAfterRegistryIndex { trailing: usize },
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl Account {
///
/// Layout:
/// - `0x00` — `UnregisteredAccount`: 32-byte Schnorr account key (`account_key_to_be_registered`).
/// - `0x01` — `RegisteredAccount`: 32-byte Schnorr account key, then 8-byte little-endian `registery_index`.
/// - `0x01` — `RegisteredAccount`: 32-byte Schnorr account key, then 8-byte little-endian `registry_index`.
pub fn encode_sbe(&self) -> Bytes {
// 1 Initialize the byte vector.
let mut bytes = Bytes::new();
Expand All @@ -36,8 +36,8 @@ impl Account {
// 2.b.2 Encode the Schnorr account key.
bytes.extend_from_slice(&registered_account.account_key);

// 2.b.3 Encode the registery index as little-endian `u64`.
bytes.extend_from_slice(&registered_account.registery_index.to_le_bytes());
// 2.b.3 Encode the registry index as little-endian `u64`.
bytes.extend_from_slice(&registered_account.registry_index.to_le_bytes());
}
}

Expand Down
Loading