A Delegated Resolution Environment for Warp Contracts.
DRE nodes are a special kind of nodes that are responsible for evaluating and serving contracts' states - in a decentralized manner - taking the burden of the state evaluation from the end users.
- The reasoning
- How it works?
- How to run?
- Future work
The purpose of implementing Warp DRE is to address the following issues.
Evaluation of high-interaction contracts - evaluating contracts with thousands of interactions is a hassle for the user's CPU. Response-time and UX can be improved significantly when computation is delegated to DRE.
Interaction with high-risk contracts - some contracts may perform risky/unsafe operations. Contract interaction via Warp DRE ensures the safety of users' devices.
Insights into PST tokens' - Providing aggregate information about PST tokens' status and count has always been challenging. With DRE's aggregation tool, one can check global address data with just a few clicks.
Avoid centralised, closed-sourced solutions - private, unknown processing logic, and tightly coupled to a specific cloud vendor (such as GCP or AWS) belong to the web2 era. Warp DRE is built on the principle of "Don't trust, verify".
With the initial testing being completed, DRE nodes are open for public participation. To run your own DRE node instance, visit here.
Currently, available nodes are:
- https://dre-u.warp.cc - a dedicated node for $U contract's evaluation
To verify if your contract is available - check the
How it works?
1. Messages processing
- The Warp Gateway and Warp Sequencer are publishing messages to a pub/sub (currently Redis, Streamr in the
future) - to a
- Two kind of messages are being sent:
- contract deployment notification (whenever a new contract is being deployed, either via Warp or directly to
- contract interaction notification (whenever a new interaction is being registered, either via Warp Sequencer
or directly to Arweave L1).
- contract deployment notification (whenever a new contract is being deployed, either via Warp or directly to Arweave L1). Message format:
- DRE is subscribing for messages on the
- DRE maintains two internal queues. The queues are implemented
- register queue for registering new contracts (for messages with an initial state)
- update queue for processing contracts' interactions (for messages with a new interaction)
- Each of the queues have its own set of workers. Each worker runs as a separate, sandboxed processor that is isolated from the rest of the code.
- Each message that comes to DRE is first validated (message format, tx id format, etc.).
- If it is a
contract deploymentnotification AND contract is not yet registered - a new job is added to the register queue.
The processor that picks up such job simply sets the
initialStatefrom the incoming message in the DRE cache.
- If it is a
contract updatenotification AND contract is not yet registered - a new job is added to the register queue.
The processor that picks up such job evaluates the contract's state from scratch.
- If it is a
contract updatenotification AND contract is already registered - a new job is added to the update queue. The processor that picks up such job either
- evaluates the state only for the interaction from the message - if DRE has a contract cached
- evaluates the state for all the interactions from the lastly cached - if D.R.E has a contract cached at a lower
sort key than
- evaluates the state only for the interaction from the message - if DRE has a contract cached at
DRE is currently using two kinds of caches
- Warp Contracts SDK's internal cache (with the LMDB plugin)
- better-sqlite3 based cache. This cache is used for
serving data via DRE endpoints - in order not to interfere
with the Warp Contracts SDK internal cache.
It also serves as a form of a backup.
WAL mode is being used for increased performance.
The evaluated state (apart from being automatically cached by the Warp Contracts SDK) is additionally:
Signed by the DRE's wallet. The data for the signature consists of:
// state is stringified with 'safe-stable-stringify', not JSON.stringify.
// JSON.stringify is non-deterministic.
const stringifiedState = stringify(state);
const hash = crypto.createHash('sha256');
const stateHash = hash.digest('hex');
const dataToSign = await deepHash([
arweave.utils.stringToBuffer(owner), // a jwk.n of the D.R.E's wallet
arweave.utils.stringToBuffer(sortKey), // a sort key at which the state has been evaluated
arweave.utils.stringToBuffer(contractTxId), // what could it be....
arweave.utils.stringToBuffer(stateHash), // a state hash
arweave.utils.stringToBuffer(stringify(manifest)), // a full node's manifest
manifest contains all the data that was used for the evaluation of the state, including
- the libraries version (warp-contracts and all warp plugins)
- the evaluation options
- git commit hash at which the node was running during state evaluation.
A manifest may look like this:
- After signing - the state is stored in the
better-sqlite3(including the validity, error messages, state hash, node's manifest at the time of evaluation, signature).
NOTE: This data allows to recreate the exact environment that was used to evaluate the state (and verify it locally).
- As a last step - a new state is being published on pub/sub
stateschannel. The messages on this channel are being listened by the Warp Aggregate Node, which combines the data from all the DREs.
To give a better understanding of that is going on, the DRE registers events at certain points of processing. Each event consists of:
- event type
- optional message
The event type is one of:
REQUEST_REGISTER- a registration request has been received for a contract
REQUEST_UPDATE- an update request has been received for a contract
REJECT- an update or registration request has been rejected either because of incoming message validation errors or because contract is blacklisted.
FAILURE- an error have occurred during contract evaluation
EVALUATED- contract has been successfully evaluated (but it required loading interactions from Warp GW)
PROGRESS- added after evaluating each 500 interactions (useful for tracking the evaluation progress of a registered contract that has thousands of interactions)
UPDATED- contract has been successfully updated using the interaction sent in the message
Whenever a contract reaches a certain amount of failures (3 for both dre-1 and dre-2) - it is blacklisted and ignored.
/status- contains information about node manifest, workers configuration, queues status, etc.
/contract- returns all data about a given contract. Parameters:
id- the contract tx id
true|false- whether state should be returned.
true|false- whether validity should be returned.
true|false- whether error messages should be returned.
errors- whether errors thrown during the evaluation process should be returned (e.g. the errors thrown by Warp Gateway, Arweave gateway).
true|false- whether events for this contract should be returned..
query- a jsonpath-plus expression that allows to query the current state (for example query for the balance of a concrete wallet address). Whenever a
queryparameter is passed, a
resultis returned instead of
/validity- returns information about interaction validity and error message content if exists
id- interaction id
contractId- id of the contract to which belongs queried interaction
/cached- returns a list of all cached contracts
/blacklist- returns all contracts that failed at least once. If contract failed 3 times - it is blacklisted.
/errors- returns all errors for all contracts
/sync- schedule force synchronization of a given contract. This endpoint can't be called more frequent then every 10 seconds. Parameters:
id- text contract tx id
HTTP/1.1 200 OK
Scheduled for update
Error when too frequent requests per one contract:
HTTP/1.1 500 Internal Server Error
Chill out and wait 10s