README
ara-reward-protocol
Ara Reward Protocol (ARP) provides methods for distributed decentralized services in the Ara Network to request work from its peers and determine the specifications of work contracts (i.e. rewards and other service-specific details).
Terminology
Farming
Performing a service for another peer in the network, potentially for a reward.
Farmer
A peer in the network who can provide a service.
Requester
A peer in the network who desires to distribute work amongst peers.
SOW (Statement-of-Work)
The scope of a distributable task, i.e. units-of-work, minimum resources, delivery date, etc.
Quote
A farmer's response to a SOW
, include cost per unit-of-work for the given SOW
.
Agreement
An agreed upon SOW
and quote between a farmer and a requester. This may reference a specific smart contract, or some other verifiable source, which can validate the details of an agreement.
Reward
A reward for a specific agreement, sent by a verifiable peer.
Receipt
A receipt for a reward, sent by a verifiable peer.
Introduction
ARP defines a set of extensible Javascript classes to enable peers of a distributed service to communicate about and define SOW
s for a specific service. Peers exchange messages in the form of reward-protocol-buffers via ARP's PeerConnection
interface.
The default interaction between a requester and a farmer is the following:
- Requester sends
SOW
to farmer - Farmer validates
SOW
and replies with quote for work - Requester validates quote and selects set of peers to complete work based on quotes
- Requester sends agreement to selected farmers
- Farmer validates agreement and countersigns agreement
- Requester validates agreement and distributes work
- If rewardable, when work is finished, requester sends reward to farmer
- Farmer validates reward and returns a receipt to requester
Status
This project is Stable.
Dependencies
Installation
$ npm i ara-reward-protocol
Usage
Extend the following classes:
Communication: Extend the PeerConnection
interface to enable your own method of communication, or use ARP's DuplexConnection
class to communicate via duplex streams.
Farming: Extend ARP's FarmerBase
class to define the specifications to generate a quote for a task, validate a peer/SOW
for a task, and to sign and validate an agreement for a task.
Requesting: Extend ARP's RequesterBase
class to define the specifications to validate peers/quotes for a task, create and validate agreements for a task, and to start work for a task. Also extend ARP's MatcherBase
class to define the specifications to select and hire a set of peers given their quotes for a task.
Note: ARP requires applications implement their own peer discovery method, such as a discovery-swarm.
API
PeerConnection
The PeerConnection interface is an abstract class that can be extended to wrap streams, RPCs, sockets, etc. The /src/duplex
folder contains an implementation of duplex streams that extends the PeerConnection interface.
/**
* Send sow to peer.
* @param {messages.SOW} sow
*/
async sendSow(sow) {
throw new Error('Extended classes must implement sendSow.')
}
/**
* Send quote to peer.
* @param {messages.Quote} quote
*/
async sendQuote(quote) {
throw new Error('Extended classes must implement sendQuote.')
}
/**
* Send agreement to peer.
* @param {messages.Agreement} agreement
*/
async sendAgreement(agreement) {
throw new Error('Extended classes must implement sendAgreement.')
}
/**
* Send reward to peer.
* @param {messages.Reward} reward
*/
async sendReward(reward) {
throw new Error('Extended classes must implement sendReward.')
}
/**
* Send receipt to peer.
* @param {messages.Receipt} receipt
*/
async sendReceipt(receipt) {
throw new Error('Extended classes must implement sendReceipt.')
}
RequesterBase
A requester must extend the RequesterBase class to define the requester's specifications for validating quotes for a task, creating and validating agreements for a task, and for starting a task.
/**
* Returns whether a quote is valid.
* @param {messages.Quote} quote
* @returns {boolean}
*/
async validateQuote(quote) {
throw new Error('Extended classes must implement validateQuote.')
}
/**
* Generate and return an agreement for a quote.
* @param {messages.Quote} quote
* @returns {messages.Agreement}
*/
async generateAgreement(quote) {
throw new Error('Extended classes must implement generateAgreement.')
}
/**
* Return whether an agreement is valid.
* @param {messages.Agreement} agreement
* @returns {boolean}
*/
async validateAgreement(agreement) {
throw new Error('Extended classes must implement validateAgreement.')
}
/**
* Called when an agreement has been marked as valid and a farmer
* is ready to start work.
* @param {messages.Agreement} agreement
* @param {PeerConnection} connection
*/
async onHireConfirmed(agreement, connection) {
throw new Error('Extended classes must implement onHireConfirmed')
}
/**
* On receipt of a reward receipt from a farmer.
* @param {messages.Receipt} receipt
* @param {PeerConnection} connection
*/
async onReceipt(receipt, connection) {
throw new Error('Extended classes must implement onReceipt')
}
FarmerBase
A farmer must extend the FarmerBase class to define that farmer’s specifications for generating a quote for a task, validating a SOW for a task, and signing and validating an agreement for a task. If rewards are expected, then a farmer would also handle validating the reward and generating a receipt.
/**
* Return whether a sow is valid.
* @param {messages.SOW} sow
* @returns {boolean}
*/
async validateSow(sow) {
throw new Error('Extended classes must implement validateSow.')
}
/**
* Return whether a reward is valid.
* @param {messages.Reward} reward
* @returns {boolean}
*/
async validateReward(reward) {
throw new Error('Extended classes must implement validateReward.')
}
/**
* Return whether an agreement is valid.
* @param {messages.Agreement} agreement
* @returns {boolean}
*/
async validateAgreement(agreement) {
throw new Error('Extended classes must implement validateAgreement.')
}
/**
* Return a receipt given a reward.
* @param {messages.Reward} reward
* @returns {messages.Receipt}
*/
async generateReceipt(reward) {
throw new Error('Extended classes must implement generateReceipt.')
}
/**
* Return a quote given a sow.
* @param {messages.SOW} sow
* @returns {messages.Quote}
*/
async generateQuote(sow) {
throw new Error('Extended classes must implement generateQuote.')
}
/**
* Sign and return an agreement.
* @param {messages.Agreement} agreement
* @returns {messages.Agreement}
*/
async signAgreement(agreement) {
throw new Error('Extended classes must implement signAgreement.')
}
/**
* Called when an agreement has been marked as valid and a requester
* is ready to start work.
* @param {messages.Agreement} agreement
* @param {PeerConnection} connection
*/
async onHireConfirmed(agreement, connection) {
throw new Error('Extended classes must implement onHireConfirmed')
}
MatcherBase
Different service requesters may have different needs when selecting peers, such as selecting the cheapest set, the fastest set, the first set number of peers, etc. To allow for this, each service may implement their own matcher (or use one of a set of predefined matchers) that extends the MatcherBase class. This class describes an object that, given a set of options, selects a subset of peers using a matching strategy specific to the service.
/**
* Add a quote for consideration. If a quote is considered
* valid, then call callback() to continue the agreement process.
* @param {messages.Quote} quote
* @param {function(messages.Agreement)} callback
* @returns {boolean} Returns whether quote was added
*/
async addQuote(quote, callback) {
throw new Error('Extended classes must implement addQuote')
}
/**
* Remove quote from consideration.
* @param {messages.Quote} quote
*/
async removeQuote(quote) {
throw new Error('Extended classes must implement removeQuote')
}