Certified HTTP Escrow
Note: This escrow service should not be confused with other forms of escrow, like the escrow used to conclude auctions or a home purchase. Though the escrow described here has a similar behavior pattern, the transactions it handles are very specific and limited.
Purpose
The escrow service is be a scalable distributed transaction coordinator for multi-host transactions. It is built on top of certified http, because reliability is a primary concern. The transactions that it implements are atomic (though not ACID), though this to some degree depends on the reliability of the participants.
Currently, the plan for the escrow is that all transactions will be modeled as a transfer of resources: an initiator supplies some parameters describing which resources will be transferred, then the escrow fetches resources, and once all resources are acquired, the escrow distributes them to their destination. If the escrow cannot gather all the resources for whatever reason, it returns the already-collected resources to their original owners. This is why it's not ACID -- the participants are not isolated from the effects of the larger transaction.
Linden Lab Usage
Linden's goals for the escrow are inspired by the real-world needs we have, but the design is a little forward-looking in that there are some things we'd like to do in the future that we should be ready to handle.
- Increase scalability by being able to make L$ transfers across arbitrary numbers of agent data stores.
- Increase reliability of transactions in general (e.g. buying objects, buying land, parcel passes, etc.)
- Some sort of API for third parties to be participants to Second Life transactions.
Model
The escrow is a resource gatherer and distributor. Every transaction goes through two phases:
- gathering phase
- In this phase, the escrow retrieves a resource from every contributing party in the transaction. If the escrow is unable to get a resource from a party, it fails the transaction.
- distribution phase
- After all the resources required for the transaction is acquired, the escrow gives the resources it has acquired to a set of receiving parties. If this phase fails, then a human must become involved.
An escrow transaction involves multiple participants, all of whom are Reliable Hosts.
- Initiator
- is the host that initiates the transaction and specifies what is going to happen and when.
- Participating party
- is any host whose existence is required for the transaction to complete.
Initiators select an escrow host using a load-balancing process, then send the chosen host a reliable message describing the transaction by name, and the parties it is to be performed between. The escrow service contains a description of the logic involved in the named transaction. In the future the escrow could theoretically implement arbitrarily-described resource-exchange transactions for known resource types. When the transaction is complete, the escrow host responds to the initiator with the results of the transaction.
Here's a sequence diagram illustrating how we think buying an object will work using the escrow.
Resources
Everything, in this system, is representable as a resource. By 'resource', we mean a token that on its own can be idempotently redeemed for something. These are just examples off the top of my head, these may not even make sense.
- L$
- a certificate of deduction on the giving agent's account, or digital cash (tm)
- Asset
- the contents of the asset (alternatively, a uuid and type for an asset on the asset server, or on a simulator)
- Parcel
- a certificate that the simulator is willing to transfer ownership of the parcel, and that it is not currently owned
Reliability
The escrow software must be a Reliable Host, with fairly strong resumption guarantees. If the escrow service crashes, it must be able to restore the state of every transaction in its care to something that only trivially differs from its state at the time of crash.
Scalability
Each escrow server, being a host for transitory executions, is completely interchangeable with any other, so there is no limit to the number of escrow hosts we could put into operation. It will be important to load-balance across them so that no individual escrow server gets overloaded.
API
Getting/Delivering Resources
The escrow must know how to take and give each type of resource in the system.
- L$
- Objects
- Parcels
- Parcel Passes
Distribution Logic
Any transaction's logic can be described as a set of parties owning the required resources, and a set of parties who should own the resources when the transaction is ended.
The distribution logic can be encoded as a set of rules, with wildcards identifying the particular details of the transaction. The initiator specifies those details.
For example, the transaction of buying an object can be represented as (this is very hand-wavey here):
{ 'gather ' : {'name':'payment', 'owner':Wildcard('buyer'), 'description':{'type':'L$', 'amount':Wildcard } } {'name':'deliverable', 'owner':Wildcard('seller'), 'description':{'type':'object', 'region':Wildcard, 'task_id':Wildcard } } } { 'distribute' : {'owner' : 'buyer', 'name': 'deliverable'} {'owner' : 'seller', 'name': 'payment'} }
Then when you want to perform this transaction, you provide:
{'transaction' : 'buy object', 'buyer' : <my_agent_id>, 'seller' : <seller_id>, 'amount' : 40, 'region' : 'Ahern', 'task_id' : 1234}
It's possible that BPEL might be a better description language for this sort of thing, but resource-based transactions are a very limited subset of all possible transactions.
Trust
The cool thing about an escrow is that it enables multiple parties who don't trust each other to nevertheless engage in a transaction of arbitrary complexity, each party trusts the escrow, and the escrow, in turn, trusts each party individually. In the case where the escrow does not trust a party, it prevents the transaction from happening, or allows the participants to individually decide whether to continue. Implementing this is not an initial design goal, however.
Current Use Cases
Here's a (possibly incomplete) list of the transactions we currently perform, that we wish to do via the escrow.
Partner
A adds B as a partner for a nominal fee. (this is sort of questionable as a use case, but it's here for discussion purposes)
A | B | Linden | |
---|---|---|---|
Gather | L$, A's agreement | B's agreement | |
Distribute | B's agreement | A's agreement | L$ |
Create Group
Creating a group for a nominal fee. (this is sort of questionable as a use case, but it's here for discussion purposes)
A | Linden | |
---|---|---|
Gather | L$ | Group token |
Distribute | Group token | L$ |
Friendship
Agent A and B agree to be friends. (this is sort of questionable as a use case, but it's here for discussion purposes)
A | B | |
---|---|---|
Gather | permissions_for_B | permissions_for_A |
Distribute | permissions_for_A | permissions_for_B |
L$ Gift
A gives B some L$.
Parties | A | B |
---|---|---|
Gather | L$ | |
Distribute | L$ |
Buy Parcel
A buys a parcel from B
Parties | A | B |
---|---|---|
Gather | L$ | Parcel |
Distribute | Parcel | L$ |
Buy Parcel for Group
A buys a parcel from B for group G
Parties | A | B | G |
---|---|---|---|
Gather | L$ | Parcel | Tier for parcel |
Distribute | L$ | Parcel |
Buy Object Contents
A buys object contents from B's object
Parties | A | B | O |
---|---|---|---|
Gather | L$ | Contents | |
Distribute | Contents | L$ |
Give Object Contents
Object O gives A its contents.
Parties | A | O |
---|---|---|
Gather | Contents | |
Distribute | Contents |
Buy Original Object
A buys B's object.
Parties | A | B |
---|---|---|
Gather | L$ | Object |
Distribute | Object | L$ |
Buy Object Copy
A buys a copy of B's object.
Parties | A | B |
---|---|---|
Gather | L$ | Object copy |
Distribute | Object copy | L$ |
Join Group
A joins group G for a fee.
Parties | A | G |
---|---|---|
Gather | L$ | Membership Pass |
Distribute | Membership Pass | L$ |
Buy Parcel Pass
A buys a parcel pass to enter B's parcel
Parties | A | B |
---|---|---|
Gather | L$ | Parcel Pass |
Distribute | Parcel Pass | L$ |
Buy Parcel Pass from Group
A buys a parcel pass to enter group G's parcel
Parties | A | G |
---|---|---|
Gather | L$ | Parcel Pass |
Distribute | Parcel Pass | L$ |
Deed Parcel
A deeds a parcel to group G.
Parties | A | G |
---|---|---|
Gather | Parcel | |
Distribute | Parcel |
Deed Parcel and Tier
A deeds a parcel and tier to group G.
Parties | A | G |
---|---|---|
Gather | Parcel, Tier | |
Distribute | Parcel, Tier |