The project implements a distributed auction system based on an IoT architecture. The system utilizes a distributed algorithm to guarantee both total and causal ordering of all bids submitted by participants.
The system relies on two core mechanisms for managing event order:
- Total Ordering: This is guaranteed by a special node designated as the Sequencer. This node is responsible for assigning a global sequence number to all auction events, ensuring that all participants process the bids in the exact same order.
- Causal Ordering: This is maintained by all participants using Vector Clocks. This mechanism ensures that the cause-and-effect relationship between messages is respected, preventing messages from being processed before the messages that causally precede them.
The architecture consists of 5 processes (nodes), implemented on ESP-32 microcontrollers.
- 1x Sequencer: This node acts as both the auction director (handling
Start Auction,Check End Auction, andEnsure Total Ordering) and as an active participant, capable of placing its own bids. - 4x Participants: These nodes can submit bids (
Send Bid) and must maintain causal consistency (Maintain Causality).
The system model assumes a closed group of
The prototype was built using the following hardware:
- 5x ESP-32 Microcontrollers
- 5x LCD Displays
- 6x Push-buttons
- Breadboards, Connectors, and 5KΩ Resistors
The system state is managed by global variables on each node, including vectorClock, sequenceNumber, highestBid, and auctionIsStarted.
Communication relies on a Message struct with the following key fields:
type: (String)start,end,bid, ororder.bidValue: (Integer) The value of the offer.vectorClock: (Array) The sender's logical clock at the time of sending.sequenceNumber: (Integer) The total order number (only valid forordermessages).senderId&messageId: (Integer) Create a unique ID for the message.
To guarantee both causal and total ordering, participants use two queues:
bidMessage Received:- The participant checks the message's
vectorClockfor causal validity. - If the message is not causally ready (a preceding message is missing), it is placed in the
HoldBackQueue. - Once its causal dependencies are met, it is moved from the
HoldBackQueueto theCausalQueue, where it waits for the total ordering message.
- The participant checks the message's
orderMessage Received:- The participant receives the
ordermessage from the Sequencer, which contains asequenceNumber. - If the corresponding
bidmessage is already in theCausalQueue, thebidis "delivered" (i.e., processed as the newhighestBid) in the correct total order (TO-Deliver). - If the
bidhas not arrived yet (or is still in theHoldBackQueue), theordermessage is held in anOrderQueue.
- The participant receives the
The Sequencer's logic is different, as it generates the total order:
bidMessage Received:- The Sequencer, acting as a participant, also validates the
bidmessage's causal order, using its ownHoldBackQueue. - As soon as a
bidis causally valid, the Sequencer immediately assigns it the nextsequenceNumber, delivers it, and broadcasts theordermessage to all other participants (TO-Send).
- The Sequencer, acting as a participant, also validates the
order,start,endMessages Received:- The Sequencer ignores these messages, as it is the original sender.
Auction.mp4
This design has several known limitations:
- Single Point of Failure (SPoF): The Sequencer is a SPoF. If the Sequencer node fails, the auction halts, as no new bids can be totally ordered.
- Bottleneck: The Sequencer must process every single
bidto assign a sequence number. This can become a performance bottleneck as the number of participants or the frequency of bids increases. - Network Assumptions: The model assumes reliable channels. If messages are lost (especially
ordermessages from the Sequencer), it can lead to inconsistencies where some nodes get stuck. Duplicate messages could also cause issues like duplicate bids or inconsistent message IDs.