Sharding represents Spicenet's approach to horizontal scaling through multiple execution shards coordinated by a consensus shard. This enables different product verticals (like spot trading, futures, etc.) to operate independently while maintaining cross-shard communication capabilities.
Unified Message Layer (UML)
Copy rustCopystruct UnifiedMessageLayer {
priority_queue : PriorityQueue < CrossShardMessage >,
connections : HashMap < ShardId , TcpStream >,
message_handlers : HashMap < MessageType , Box < dyn MessageHandler >>
}
impl UnifiedMessageLayer {
async fn handle_cross_shard_message ( &mut self, msg : CrossShardMessage ) -> Result <()> {
// Log message receipt
tracing :: debug! ( "Received cross-shard message: {:?}" , msg);
// Get appropriate handler
let handler = self . message_handlers . get ( & msg . message_type)
. ok_or (Error :: UnknownMessageType ) ? ;
// Process message
handler . handle_message (msg) .await? ;
Ok (())
}
async fn send_priority_message ( &mut self, to_shard : ShardId , msg : CrossShardMessage ) {
self . priority_queue . push (msg . clone (), msg . priority);
// Process high priority messages immediately
while let Some (high_priority_msg) = self . priority_queue . pop_if_priority_exceeds (PRIORITY_THRESHOLD) {
if let Some (conn) = self . connections . get ( & to_shard) {
conn . send_message (high_priority_msg) .await? ;
}
}
}
}
Here's how the system handles an atomic swap between the spot and futures shards:
Copy rustCopy // Define the atomic swap
struct AtomicSwap {
from_shard : ShardId ,
to_shard : ShardId ,
from_asset : Asset ,
to_asset : Asset ,
user : AccountId
}
// Implementation of cross-shard atomic swap
async fn execute_atomic_swap (
uml : &mut UnifiedMessageLayer ,
swap : AtomicSwap
) -> Result < SwapResult > {
// 1. Lock assets in source shard
let lock_msg = CrossShardMessage {
message_type : MessageType :: LockAssets ,
priority : Priority :: High ,
payload : swap . from_asset . serialize (),
user : swap . user
};
uml . send_priority_message (swap . from_shard, lock_msg) .await? ;
// 2. Verify lock confirmation
let lock_conf = uml . await_confirmation (swap . from_shard) .await? ;
// 3. Execute swap in destination shard
let swap_msg = CrossShardMessage {
message_type : MessageType :: ExecuteSwap ,
priority : Priority :: High ,
payload : swap . to_asset . serialize (),
user : swap . user
};
uml . send_priority_message (swap . to_shard, swap_msg) .await? ;
// 4. Wait for swap confirmation
let swap_conf = uml . await_confirmation (swap . to_shard) .await? ;
// 5. Release original assets
let release_msg = CrossShardMessage {
message_type : MessageType :: ReleaseAssets ,
priority : Priority :: High ,
payload : swap . from_asset . serialize (),
user : swap . user
};
uml . send_priority_message (swap . from_shard, release_msg) .await? ;
Ok ( SwapResult {
status : SwapStatus :: Completed ,
from_conf : lock_conf,
to_conf : swap_conf
})
}
// Usage example
let swap = AtomicSwap {
from_shard : ShardId :: Spot ,
to_shard : ShardId :: Futures ,
from_asset : Asset :: SpotBTC ( 1 . 0 ),
to_asset : Asset :: PerpBTC ( 1 . 0 ),
user : user_account
};
let result = execute_atomic_swap ( &mut uml, swap) .await? ;