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
This commit is contained in:
parent
39c87fd103
commit
267f9115ba
|
@ -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.
|
Loading…
Reference in New Issue