Excited to share that we’ve launched our own Solana validator on mainnet!(8vk6QpG93JSaQCSgnycBsv5qmfQBk4qC9FjNA35E5JhU)
- 0% commission
- 0% MEV commission
- Proceeds fund OSS contributions by @anoushk77 and @harsh_patel
We’ve been quiet for a while. Here’s why and what we were up to...
Excited to announce that our Simplified Payment Verification (SPV) client is live on @solana Testnet! 💃🤏
Here’s our incredible journey after 5 iterations, challenges and demo 🧵
Your solana transactions might be in danger and you can’t do anything about it. Until now.
Introducing Tinydancer - the first light client on @solana
Let's dive in! 👇
We are beyond thrilled to share that we’ve won in the Infra track! Thanks to everyone that’s contributed to Tinydancer in some way ❤️
@toly @dubbel06 @shek_dev@kashdhanda@akshaybd@neilshroff@clockwork_xyz
We have some exciting things coming up😉
Simple payment verification without running a full node is a fundamental need in any payment system. Satoshi knew it and hence we have this excerpt from the Bitcoin whitepaper.
They're the first stage of light clients. Solana will soon have it 💯
Our team will be giving a live demo of Tinydancer, @solana's first light client at the Vietnam Hacker House! 🇻🇳
Catch @anoushk77 and @harsh_patel in-person demoing Simple payment verification on mobile using tinydancer! 🤏💃
2. diet clients - 1/N assumptions for safety. Votes should sign a merkle root for turbine shreds, clients can sample a bunch of nodes for shreds and confirm that honest nodes aren't eclipsed and computed the same bankhash. Prevents corrupt majority attacks!
We see a lot of misconceptions around our client.
Our SPV client is not 100% trustless.
SPV client relies under the assumption that 2/3rds of the network stake or supermajority of the network is honest.
Trust assumptions are tiered.
We’re extremely elated that @0xNineteen opened the first open source PR to Tinydancer 🔥
We love the enthusiasm and altruistic spirit, if you’re looking to contribute feel free to open a PR🫡
github.com/tinydancer-io/hal…
We'd also like to show our gratitude to the team at @_cubik and our valuable supporters from our Cubik grants round. Their support has been incredibly impactful in our progress.
Last but definitely not the least, we'd like to thank @SuperteamDAO for believing in us early on.
Our initial design went through four different iterations (with 5 different SIMDs):
• First Design - Our very first design (SIMD 0023 - diet client v0): github.com/tinydancer-io/sol…
• Second design - Modifying the blockhash to be computed as a tree: github.com/tinydancer-io/sol…
Now SIMD-0052 & 0064 work in theory but the mechanism itself required modifying Bankhash construction, which is a consensus breaking change.
Consensus breaking changes can be critical to the reliability and safety of a blockchain network, a minor bug can risk a liveness failure.
A Bankhash is an aggregated commitment of Accounts Delta hash, parent bank hash, signature count buffer and the last committed block hash that is constructed every block.
Although fraud proofs would require a state root for every block something that @toly and @solanalabs have in their roadmap.
This was a very high level explanation of how tinydancer works and we will soon be releasing a more in-depth whitepaper for all the comp sci nerds.
This is when @dubbel06 & @prestonevans__ from @sovereign_labs came up with a novel mechanism that didn't require any consensus breaking changes.
The plan was to use the `accounts_delta_hash` (an already existing component) which is rolled into the Bankhash.
We believe there's a large opportunity to create a parallel DA layer for Solana starting with out light client.
What this means is that we can have a per block state root in solana & validators can be incentivized to produce it without affecting block times
We are also working on a Typescript SDK which will make it easier for clients to seamlessly integrate it inside frontends or wallets. Here's a link to the repository for the SPV plugin:
github.com/tinydancer-io/sol…
Now at a high level, Solana blockchain has the following network participants:
• A validator node: Responsible for consensus and security of the chain. One of which becomes a block producer and processes transactions, called a Leader Node.
Accounts delta hash is a root of a 16-ary merkle tree of accounts that get changed in a particular slot, hence the "delta" in the terminology.
The idea was to use a globally scoped program (copy program) that modifies a globally scoped PDA whenever a user wants to send the txn.
Tinydancer would also connect to it's own network of light clients using p2p communications to create it's own DA plane.
This would enable features such as:
- Private Repair Network
- On-Demand Verification
The Private Repair Network:
It would help full nodes and validators repair their blocks significantly faster with the help of the Tinydancer DA plane.
Traditional repair is very slow and hence having faster repair would be a massive improvement for validators.
To include a receipt root, we would need to modify the `hashv()` function's arguments.
Additionally, we would also need to modify parts of consensus and runtime for the process of constructing the receipt tree itself.
Now this may seem like a very simple change, but the impact overall is non-trivial.
The receipt tree construction itself would require rigorous testing and bench-marking.
• Full node - Nodes that don't participate in consensus but do verify the state of the chain and serve on chain data to clients/users.
• Clients: This could be any app/website consuming on-chain data for their functionality like wallets, payment apps, DEXs etc
You're in a hurry and this Monke is very important for you. You pick your favourite one and place a buy order.
Your transaction succeeds and the funds are deducted from your wallet. But here's a catch...
Validators vote on the bankhash and when a particular block receives >= 2/3rds of the total active stake, we can conclude that the transaction has been confirmed under an honest supermajority.
For more details on account inclusion proof refer here:
github.com/tinydancer-io/sol…
Since accounts_delta_hash only includes accounts which are changed in that particular slot, the trick is to call the copy program in every arbitrary transaction that will modify the state of the PDA.
Hence we get a guaranteed path from the leaf (our account) to the Bankhash.
Imagine you want to buy an NFT from your favourite collection on @hyperspacexyz or @MagicEden, let's say its a @SolanaMBS Monke.
You open your favourite hot wallet and connect it to the website.
How can someone verify the state of their particular transaction without having to go down the trouble of setting up a node.
This is a fundamental security issue that needs to be addressed since majority of the normal users can't afford to run a full node.
In your case it might've been that one of the RPC provider was a part of a corrupt Supermajority and they were colluding against your particular transaction(we're looking at you @colludingnode).
They approved a fraud txn and finalized the block containing that transaction.
But if corrupt nodes don't send the block to the honest node and essentially eclipse it from the network then the user will never know.
This is where the light client uses DA sampling to ensure the block data is always available to everyone in the network.
We achieve this by Data Availability or DA sampling. Let's take an example:
Assume there are 100 nodes, out of which 99 are corrupt and only of them is honest. If the honest node receives the block and verifies that it is invalid or fraudulent then the user can be notified.
So how do you protect against such corrupt supermajority attacks?
Enter Tinydancer - Solana's first light client implementation.
If you're running the client, you can ask any full node - "what's the status of this txn? Can you tell me if it was included in a valid block?"
You don't see the Monke in your wallet. It just isn't there!
You panic and go to several discords asking for help. They ask you to switch your RPC provider but you don't know what that is....
Moving on to On-Demand Verification:
This will be a service similar to the solana-ledger-tool that allows users to pay validators verify a slot in the snapshot.
A user can pay and query N validators and if M/N validators respond with a valid response then user can accept that.
Now for any transaction like yours to be confirmed and finalized,
the network should reach a consensus on your particular transaction.
Specifically, 2/3 of the consensus participating nodes (called Supermajority) should agree that your transaction is valid and approved.
You finally decide to check the explorer and the explorer shows you that the transaction was successful and there is a Monke in your wallet.
Now you wonder who's lying to you, is it your precious wallet or is it the explorer? 🤔
2. diet clients - 1/N assumptions for safety. Votes should sign a merkle root for turbine shreds, clients can sample a bunch of nodes for shreds and confirm that honest nodes aren't eclipsed and computed the same bankhash. Prevents corrupt majority attacks!
Honored to get a shoutout from @MikeIppolito_ on the latest @bankless episode!
It's great to hear Solana's work on decentralisation (esp. light clients) getting the recognition it deserves.
piped.video/watch?si=8Ucrt…
This is a tough situation, you have no idea what to do other than sit back disappointed and mourn the loss of your funds.
Clearly a fraud has occurred but you don't know who to trust and who not to 🤷♂️
Now in case the one honest nodes finds an invalid block, it can produce a fraud proof and send it to the light client.
With this the client doesn't have to trust the honest node, it can just verify the cryptographic proof and check if the block is fraudulent or not.
❓ Why is this needed?
Currently, there's no way to verify that a transaction has been included in a particular block.
Ideally, we want to be able to verify this locally, on any user's device, like a smartphone for instance.
You can’t say “my chain scales and yours doesn’t” until it has working trust-minimized light clients.
It’s like saying “my car goes faster than yours” when neither car can even start.
A blockchain doesn’t serve its purpose if it’s users are trusting intermediaries to use it.
If you're interested in how these changes are used in the light client, you can refer to this diagram alongside the detailed design section in the SIMD.
github.com/tinydancer-io/sol…
To address these issues we proposed a change in the calculation of blockhash to:
- Construct a merkle tree of entries instead of a hash
- Include the txn status in the merkle tree of the batch of transactions that are part of the entry.
Additionally, we want to thank @m_schneider for his suggestion to include txn logs in the Merkle which will also be part of the SIMD soon. github.com/solana-foundation…
First, what is a light client?
A cluster participant that does not itself run a full node ( validator, RPC node ) but has trust minimized access to the network without large hardware requirements.
Your solana transactions might be in danger and you can’t do anything about it. Until now.
Introducing Tinydancer - the first light client on @solana
Let's dive in! 👇
For the v0 of our client, we're focusing on a simple payment verification (SPV) client that verifies
- A particular transaction of interest has been included in a block
- The block has been voted on by a trusted set of validators based off this proposal
docs.solana.com/proposals/si…
In conjunction to these changes we proposed a new RPC method to get proofs of transaction inclusion. These proofs are used to compute to the root i.e. the bankhash, locally.
1. Verifying txn inclusion would require all the entries to be hashed again which is more computationally intensive.
2. We cannot verify if a transaction is successful even if it is included as statuses are not part of the blockhash
Each slot is identified by a bankhash containing:
- Parent hash: bank hash of the parent block.
- Accounts delta hash: hash of all modified accounts
- Signature count: Number of signatures processed in this block
- Recent blockhash: Last PoH hash in this block