Sharding Implementation
Last updated
Last updated
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.
The UML is crucial for enabling efficient cross-shard communication:
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?;
}
}
}
}
Example: Cross-Shard Atomic Swap
Here's how the system handles an atomic swap between the spot and futures shards:
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?;