From 267f9115ba880cbb0cff77ec8b6acdcd7521528f Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Wed, 14 Nov 2018 15:19:34 -0800 Subject: [PATCH] Add drone RFC (#1754) * Add stamps RFC * Don't use the language 'load the program' * Replace stamps RFC with new more general drone design * Fix typo * Describe potential techniques for getting recent last_ids --- rfcs/0010-drones.md | 113 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 rfcs/0010-drones.md diff --git a/rfcs/0010-drones.md b/rfcs/0010-drones.md new file mode 100644 index 0000000000..d6e76f1cdb --- /dev/null +++ b/rfcs/0010-drones.md @@ -0,0 +1,113 @@ +# Drone 1.0: A Signing Service + +The goal of this RFC is to define a microservice called a *drone*, which acts +as custodian of a user's private key. In its simplest form, it can be used to +create *airdrop* transactions, a token transfer from the drone's account to a +client's account. + +## Background + +At the time of this writing, Solana contains an undocumented microservice +called a drone. A client sends that drone a request for tokens and it then +interacts with the Solana cluster directly to put the airdrop transaction on +the ledger. Once confirmed, the drone returns its signature so that a client +may also confirm the transaction. + +The intent of the current design was that it be used by clients wanting to +test-drive the Solana testnet. We did not intend for it to be used in mainnet, +but recently we found variations of it are generally useful and so offer an +updated design. Specifically, we have found that program owners may want to +publish a drone such that potential program users may instantiate their +programs without first owning any tokens. The program owner can use the +existing drone to enable these users, but the approach is unsatisfying for a +number of reasons: + +1. Once the client has tokens to instantiate the program, the client may choose + to simply keep them. +2. Instantiating a program requires two transaction fees - one for the airdrop + and one to instantiate the program. +3. The drone uses its own resources to interact with the Solana cluster + directly. This artificially limits the number of users it can serve and + opens the drone to DoS attacks. + + +## Signing Service + +To solve the problems described above, the drone shall be reduced to a simple +signing service. It shall listen for requests to sign *transaction data*. Once +received, the drone should validate the request however it see fit. To +implement the existing drone, for example, it may only accept transaction data +with a `SystemProgram::Move` instruction transferring only up to a certain +amount of tokens. If the drone accepts the transaction, it shall return an +`Ok(Signature)` where `Signature` is a signature of the transaction data using +the drone's private key. If it rejects the transaction data, it should return a +`DroneError` describing why. + + +## Examples + +### Granting access to an on-chain game + +Creator of on-chain game tic-tac-toe hosts a drone that responds to airdrop +requests containing an `InitGame` instruction. The drone signs the transaction +data in the request and returns it, thereby authorizing its account to pay the +transaction fee and as well as seeding the game's account with enough tokens to +play it. The user then creates a transaction for its transaction data and the +drones signature and submits it to the Solana cluster. Each time the user +interacts with the game, the game pays the user enough tokens to pay the next +transaction fee to advance the game. At that point, the user may choose to keep +the tokens instead of advancing the game. If the creator wants to defend +against that case, they could require the user to return to the drone to sign +each instruction. + +### Worldwide airdrop of a new token + +Creator of a new on-chain token (ERC-20 interface), may wish to do a worldwide +airdrop to distribute its tokens to millions of users over just a few seconds. +That drone cannot spend resources interacting with the Solana cluster. Instead, +the drone should only verify the client is unique and human, and then return +the signature. It may also want to listen to the Solana cluster for recent +entry IDs to support client retries and to ensure the airdrop is targeting +the desired cluster. + + +## Attack vectors + +### Invalid last_id + +The drone may prefer its airdrops only target a particular Solana cluster. To +do that, it listens to the cluster for new entry IDs and ensure any requests +reference a recent one. + +Note: to listen for new entry IDs assumes the drone is either a fullnode or a +*light* client. At the time of this writing, light clients have not been +implemented and no Solana RFC describes them. This document assumes one of the +following approaches be taken: + +1. Define and implement a light client +2. Embed a fullnode +3. Query the jsonrpc API for the latest last id at a rate slightly faster than + ticks are produced. + +### Double spends + +A client may request multiple airdrops before the first has been submitted to +the ledger. The client may do this maliciously or simply because it thinks the +first request was dropped. The drone should not simply query the cluster to +ensure the client has not already received an airdrop. Instead, it should use +`last_id` to ensure the previous request is expired before signing another. +Note that the Solana cluster will reject any transaction with a `last_id` +beyond a certain *age*. + +### Denial of Service + +If the transaction data size is smaller than the size of the returned signature +(or descriptive error), a single client can flood the network. Considering +that a simple `Move` operation requires two public keys (each 32 bytes) and a +`fee` field, and that the returned signature is 64 bytes (and a byte to +indicate `Ok`), consideration for this attack may not be required. + +In the current design, the drone accepts TCP connections. This allows clients +to DoS the service by simply opening lots of idle connections. Switching to UDP +may be preferred. The transaction data will be smaller than a UDP packet since +the transaction sent to the Solana cluster is already pinned to using UDP.