Skip to content

Saline Architecture

Chain and Consensus

Saline is a proof-of-stake (PoS) chain implemented as the ABCI layer on Tendermint. The ABCI layer contains the application logic eg state machine, txs, signatures etc. Whereas Tendermint handles consensus, block proposal and voting.

Consensus & Networking layer

  • validator set design
  • block time
  • how validators reach consensus
  • deterministic finality
  • P2P networking model

The validator set is a curated group of nodes responsible for block proposal and validation. Each validator possess a unique cryptographic key pair, and is assigne a specific voting power, which may vary among validators. The initial validator set consists of 100 nodes. Initially these will be operated by the Saline.Network team, but will be delegated to node operators and the community in general in time. Subsequent changes to the set are managed through the ABCI application’s EndBlock response, allowing for dynamic updates based on staking, governance decisions, or other criteria.

TIP

validators are encouraged to implement a sentry node architecture to prevent the direct exposure of validator nodes nodes by shielding them behind public sentry nodes, which handle peer-to-peer communications. Thus reducing the risk of Distributed Denial of Service (DDoS) attacks.

Block time is 10 seconds, balancing throughput and network stability.

Consensus Mechanism The Saline network uses the Tendermint Byzantine Fault Tolerant (BFT) consensus algorithm, as implemented in CometBFT v0.34. This algorithm ensures that all non-faulty validators agree on the same sequence of blocks, even in the precense of malicious actors. A block is only committed when a supermajority (>2/3) of validators agree, providing strong consistency and fault tolerance

The consensus process operates in a series of rounds, each consisting of the following steps:

  1. Proposal: A designated proposer broadcasts a new block proposal to the validator set
  2. Prevote: Validators broadcast a prevote for the the proposed block
  3. Precommit: If a validator recieves prevotes from more than 2/3 of the validator set for the same block, it broadcasts a precommit for that block.
  4. Commit: Once a validator receives precommits from more than 2/3 of the validator set for the same block, it commits the block to the chain.

P2P Networking model Built upon the CometBTF modular networking stack for secure and efficient communication between nodes. Key components include:

  • Authenticated and Encrypted Connections
  • Peer Exchange
  • Reactor Pattern
  • Sentry Nodes

Application Layer

Implemented as the ABCI layer, the main key modules in Saline details handling intents, transactions and accounts. Intents in Saline are firstly installed on-chain via special transactio instructions. These simple plain-text predicates are then evaluated by validators when an entity want to move funds to or from an address. Transactions are simple maps. The state transition model follows the standard CometBFT/Tendermint flow:

  • BeginBlock
  • DeliverTx
  • EndBlock
  • Commit
  Tx: { from: alice, to: bob, amount: 100 }

  DeliverTx:
  - Check balance of Alice
  - Subtract 100 from Alice
  - Add 100 to Bob
  - Update KV store

  Commit:
  - Recalculate AppHash from store root

Security

The use of CometBFT provides deterministic finality. Once a block is committed to the blockchain, it is considered final and irreversible, assuming that less than one-third of validators are faulty or malicious. In contrast, probabilistic finality, as seen in Proof-of-Work (PoW) systems like Bitcoin, considers a transaction increasingly final as more blocks are added on top of it, but there’s always a non-zero chance of reversal. Deterministic finality ensures immediate and absolute finality upon block commitment, which is crucial for applications requiring strong consistency guarantees.

For a declarative intent system like Saline, deterministic finality offers significant benefits

  • Predicatble Execution: Intents in Saline represents a desired outcome or condition. Deterministic finality ensures that once an intent is executed, or matched against and included in a block, its outcome is final.
  • Enhanced Security: mmediate finality reduces the window of vulnerability where transactions could be reversed, which is vital for operations relying on the immutability of prior states, eg cross-chain, options and futures.
  • Simplified State management: Deterministic finality allows developers not having to take potential rollbacks into account when building their applications on Saline.

The cornerstone of Saline is the intent system. Intents can enable and constrain everything from P2P swaps to delegate spending rights for DEXes.

I want to trade BTC/ETH on an exchange without giving up my private key. The following code snippet allows the dex owning dex_public_key to send BTC and ETH from my_wallet (for using in their own orderbooks) for the next 24 hours.

python
  import time
  availableAfter = false
  expiry_time = int(time.time()) + (24 * 60 * 60)
  delegate_condition = Signature(dex_public_key) & (Send(Token.BTC), Send(Token.ETH))
  temporary_intent = Temporary(expiry_time, availableAfter, delegate_condition)
  set_intent_instruction = SetIntent(my_wallet.public_key, delegate_condition)

We can arbitrarily extend these rules with more logic, ie constraining amounts, limiting conterparties we're willing to receive such funds from etc, require counterparties wishing to send us funds to be approved by a KYC oracle etc. [alex insert]

python
delegate_condition = Signature(dex_public_key) & (Send(Token.BTC), Send(Token.ETH))
counterparty_restriction= Oracle(KYC_approved) & (Receive(Token.BTC), Send(Token.ETH))
intent= All(Counterparty, delegate_condition)
temporary_intent = Temporary(expiry_time, availableAfter, delegate_condition)

This sort of magic wallet esque dex trading has two enforcement points in the chain. If the DEX submits a transaction it's not authorised to do, the CheckTx hook denies the transaction before it gets added to the mempool. If however a transaction is valid, but then say the KYC oracle reject the counterparty, DeliverTx will mark the Tx as failed.

AspectCheckTxDeliverTx
InvocationUpon receiving a new transactionDuring block commitment
PurposePreliminary validation for mempoolExecute transaction and update state
State ChangesNoneApplies changes to application state
Consensus RolePre-consensusPart of consensus process
Error HandlingRejects invalid transactions earlyMarks failed transactions; block may proceed

Cryptography

All keys in Saline are BLS-12-381 private keys, following the IETF-specification. Key derivation is implemented per EIP-2333 specification. And keys are BIP 44 compliant, while not registered. Private keys are 32 bytes, public keys 48 bytes (G1) and signatures 96 bytes (G2).

The use of BLS allow for optimisations and key features, such as non-interactive m/n thresholds by leveraging the additively homomorphic properties of BLS and aggregated signatures and keys takes up the same amount of bytes as single signatures.