Skip to content

Commit

Permalink
add sips i contrinuted to
Browse files Browse the repository at this point in the history
  • Loading branch information
lilyannehall committed Nov 16, 2024
1 parent 6608ce1 commit 3ae16d9
Show file tree
Hide file tree
Showing 3 changed files with 446 additions and 0 deletions.
202 changes: 202 additions & 0 deletions Storj/sip-0003.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
```
SIP: 3
Title: Remote Notifications and Triggers
Author: Lily Anne Hall
Status: Active
Type: Standard
Created: 2016-08-10
```

Abstract
--------

Protocol extension that gives nodes the capability to opt-in to passive generic
notifications from other nodes and services as well as authorize certain types
of notifications and senders to trigger behavior within client applications
implementing this SIP.

Motivation
----------

Applications implementing the Storj protocol are designed for a variety of
use-cases and the resulting relationships between applications on the network
can become far more nuanced than a simple 1-1 transaction. To illustrate this
we cite the introduction of [Storj Bridge](https://github.com/storj/bridge) as
a broker between a "thin client" renter and a farmer.

The introduction of a broker brings with it the need for arbitration measures
in the event that one of the parties acts outside of the terms of the storage
contract. Given that it is difficult to predict how future systems will
implement these measures, we propose a generic notification format to allow
nodes to invent meta-protocols that may trigger application specific behaviors.

### Example: Farmer Information Requests

Organizations (like Storj Labs) may be responsible for collecting information
from farmers due to regulatory compliance and tax purposes when issuing payouts
above a certain amount. To notify a farmer when that information needs to be
provided, the Storj Share client application could opt-in to receive triggers
from Storj Labs to show a prompt when the owed amount exceeds a threshold.

### Example: Third Party Transfer Verification

Contract brokers, like the operator of a Storj Bridge, need to know when a data
transfer between two parties succeeds or fails so that it can appropriately
track the performance and reliability of the farmers it selects in the future.
The method for implementing these proofs and verifications is outside the scope
of this SIP, however it is likely that there will be a number of future
strategies for carrying out this work. To avoid the need for a new strategy to
become accepted into the core protocol, nodes that support the given strategy
can use these custom triggers to request and deliver the information needed to
carry them out.

Specification
-------------

This SIP proposes the addition of a new protocol extension to add a `TRIGGER`
RPC message for the purpose of sending a custom payload to a consenting node on
the network. The intent is to allow nodes to establish a relationship with each
other that grants one or both parties license to "trigger" some behavior in the
software running on the other party's host.

### Message Format

This specification does not rigidly define any application behaviors - it's only
purpose is to define the message structure and rules surrounding how an
application-specific trigger should be issued and handled. Like the rest of the
[Storj Protocol](http://storj.github.io/core/tutorial-protocol-spec.html), this
message is formatted according to the JSON-RPC 2.0 definition and includes all
of the standard required Storj protocol parameters.

In addition to the required parameters, the `TRIGGER` method requires:

* **behavior**: *String* - Arbitrary identifier for the behavior to trigger
* **contents**: *Object* - Dictionary of named parameters and their values

Below is a possible example of a trigger that might be sent from a farmer to a
third party bridge node to prove that she successfully received all of the data
from a renter whose storage contract was brokered by the bridge:

```json
{
"method": "TRIGGER",
"params": {
"behavior": "ProveUploadReceipt",
"contents": {
"rmd160sha265": "cebaa98c19807134434d107b0d3e5692a516ea66",
"sha1whirlpool": "43144cac0a406eb72f4d3be7292438ac15725e1d"
},
"contact": {
"address": "10.0.0.2",
"port": 1337,
"nodeID": "89cc3ddb4209c6e7e301c10c0257adf4fd85f253",
"protocol": "0.7.2"
},
"nonce": 1455216323786,
"signature": "3045022100de2e162d017a1e9d0ebfe2a94df3fc847b68281a9882..."
},
"id": "7b6a2ab35da6826995abf3310a4875097df88cdb"
}
```

In the example above the renter has provided the bridge with two different
hashes of the data it wishes to upload. The bridge publishes a contract to the
network that is keyed on the RMD-160(SHA256(data)), so that hash is known. Once
the bridge negotiates a contract with a farmer and brokers the data channel,
the farmer must prove to the bridge that she received all of the data from the
renter by calculating the second secret hash from the transferred data.

Once the secret hash is calculated, the farmer sends a `TRIGGER` to the bridge
(who has authorized the trigger previously and is expecting it) that includes
both hashes. This would trigger a behavior in the bridge to update it's record
that the farmer did receive the data.

> Note that the `ProveUploadReceipt` behavior is *not* part of the Storj
> protocol, but is an **application-specific** trigger that must be implemented
> by the both the client software and the target node.
Likewise, the response to a trigger message follows the Storj protocol and can
include any arbitrary response values:

```json
{
"result": {
"message": "Upload proof successfully recorded",
"contact": {
"address": "api.storj.io",
"port": 4001,
"nodeID": "98dc026fa01ae26822bfb23f98e725444d6775b0",
"protocol": "0.7.2"
},
"nonce": 1455216323786,
"signature": "904502207e8a439f2cb33055e0b2e2d90e775f29d90b3ad85aec0c..."
},
"id": "7b6a2ab35da6826995abf3310a4875097df88cdb"
}
```

To further clarify the point, the `TRIGGER` message format and the advisements
for handling should become an extension to the Storj protocol, but the types
of behaviors and their associated content may remain **application-specific**,
or alternatively, be proposed as their own SIP if desired. The trigger RPC acts
as a sort of envelope for any number of sub-protocols that tenants of the
Storj network may implement and adopt without the need to reach community
consensus as the handling of triggers is up to each individual application.

### Authorization Practices

Clients choosing to implement support for triggers should take care to provide
a safe interface for enabling triggers. To ensure that application behavior can
only be triggered by parties that have been explicitly authorized to do so, the
minimum best practices to follow are:

* Triggers are only enabled on a *whitelist* and *opt-in* basis
* Whitelist is based on `nodeID` *and* `behavior`
* Add a trigger to the whitelist only when you are expecting it
* Remove the trigger from the whitelist when you are longer expecting it
* Process all messages, *especially triggers*, after signature verification

#### Example Code

Assuming the use of [Storj Core](http://storj.github.io/core), authorizing a
trigger might resemble the following:

```js
var storj = require('storj');
var network = new storj.RenterInterface(options);

// When a contract is negotiated and data channel is authorized...
network.triggers.add(farmerNodeId, {
ProveUploadReceipt: function(msgParams, replyToSender, destroyTrigger) {
var secretHashExpected = somehowGetSecretHash();
var secretHashReceived = msgParams.contents.sha1whirlpool;

// If the provided hash doesn't match, then respond with error and destroy
// this trigger handler (to be added again when needed)
if (secretHashReceived !== secretHashExpected) {
replyToSender(new Error('Invalid secret hash provided'));
return destroyTrigger();
}

// Update our record of the farmer's receipt of the data and respond with
// an acknowledgement
somehowUpdateThisFarmersRecord();
replyToSender(null, { message: 'Upload proof successfully recorded' });
destroyTrigger();
}
});
```

This example demonstrates a safe interface for accepting triggers for a couple
of reasons:

1. The implementor must explicitly define a trigger handler for the Node ID
2. The implementor must explicitly define the expected behavior to handle
3. The implementor is provided an interface to easily unregister the trigger

Other Use Cases
---------------

* IoT integration with a Storj farm (power management, failure recovery, etc)
* Automatic notification of renter/bridge when a farmer is shutting down
* Web of trust based blacklisting or "tattling" on bad actors
142 changes: 142 additions & 0 deletions Storj/sip-0004.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
```
SIP: 4
Title: Contract Transfers and Renewals
Author: Lily Anne Hall
Braydon Fuller
Status: Active
Type: Standard
Created: 2016-10-26
```

Abstract
--------

The SIP introduces a new RPC method to the Storj protocol to enable renting
actors on the network to instruct the custodians of their data to modify
certain contract terms for a given shard.

Motivation
----------

This addition solves two immediate problems:

1. Efficiently renewing existing contracts without the neccessity of publishing
entirely new ones to extend the length of storage time.
2. Providing an upgrade path for [HD Identity](sip-0032.md) transfer from a
standard Node ID.

Specification
-------------

We propose a new RPC method, `RENEW`, which may be issued to a farming node at
any time to modify the terms of a contract for which the issuing party is
authorized. In addition to the standard required parameters, the `RENEW` RPC
includes 3 more:

* **contract** - the new modified/updated contract data
* **renter_id** - the Node ID authorized for the original contract
* **renter_signature** - the new contract signature by the original Node ID

### Message Format

When a renting node wishes to modify the terms of a given storage contract,
it issues a `RENEW` RPC message to the farmer including the required
parameters. Not all contract parameters may be modified in a contract renewal,
the allowed modifications are limited to:

* **renter_id**
* **renter_hd_key**
* **renter_hd_index**
* **renter_signature**
* **store_begin**
* **store_end**

Recipient farmers must take care to validate the modifications to prevent loss
of future payments. In the example below, a renting node is instructing the
farming node to transfer the authorization/ownership to a new SIP32 based
identity as well as extending the contract period by an additional 90 days.

```json
{
"method": "RENEW",
"params": {
"renter_id": "43144cac0a406eb72f4d3be7292438ac15725e1d",
"renter_signature": "3045022100de2e162d017a1e9d0ebfe2a94df3fc847b68281a...",
"contract": {
"version": 0,
"renter_id": "608939ffcaac7d8019ab43bd097124025d3c47e9",
"renter_hd_key": "xpub6AMzSjSPt3Dc3Z1nziingqQcbHFLtKMsVjYXW1HSPDFihcj...",
"renter_hd_index": 0,
"renter_signature": "3045022100de2e162d017a1e9d0ebfe2a94df3fc847b6828...",
"farmer_id": "8d225ed9aec6e2dfb74d51c84c58ff13d11cfa79",
"farmer_signature": "3045022100de2e162d017a1e9d0ebfe2a94df3fc847b6828...",
"data_size": 8388608,
"data_hash": "e6114b9763d433808f6fdf632c00b919a439bc97",
"store_begin": 1477505878758,
"store_end": 1485281902724,
"audit_count": 3,
"payment_storage_price": 0,
"payment_download_price": 0,
"payment_destination": "1DL5N2ayoUxHwgD2NEZ4ifq1wVRVLVQyk2"
},
"contact": {
"address": "10.0.0.2",
"port": 1337,
"nodeID": "89cc3ddb4209c6e7e301c10c0257adf4fd85f253",
"protocol": "0.7.2"
},
"nonce": 1455216323786,
"signature": "3045022100de2e162d017a1e9d0ebfe2a94df3fc847b68281a9882..."
},
"id": "7b6a2ab35da6826995abf3310a4875097df88cdb"
}
```

Upon receipt of a `RENEW` RPC, the farmer must inspect the contract and
perform a local lookup of any contracts associated with the given `data_hash`.
If a contract is found for the shard and the original `renter_id`, then the
farmer must verify the signature from the original identity and validate the
contract modifications - including signature verification for the new identity.

If these checks pass, the farmer must sign the new contract and respond to the
request with it's updated copy after updating it's own local record.

```json
{
"result": {
"contract": {
"version": 0,
"renter_id": "608939ffcaac7d8019ab43bd097124025d3c47e9",
"renter_hd_key": "xpub6AMzSjSPt3Dc3Z1nziingqQcbHFLtKMsVjYXW1HSPDFihcj...",
"renter_hd_index": 0,
"renter_signature": "3045022100de2e162d017a1e9d0ebfe2a94df3fc847b6828...",
"farmer_id": "8d225ed9aec6e2dfb74d51c84c58ff13d11cfa79",
"farmer_signature": "3045022100de2e162d017a1e9d0ebfe2a94df3fc847b6828...",
"data_size": 8388608,
"data_hash": "e6114b9763d433808f6fdf632c00b919a439bc97",
"store_begin": 1477505878758,
"store_end": 1485281902724,
"audit_count": 3,
"payment_storage_price": 0,
"payment_download_price": 0,
"payment_destination": "1DL5N2ayoUxHwgD2NEZ4ifq1wVRVLVQyk2"
},
"contact": {
"address": "api.storj.io",
"port": 4001,
"nodeID": "98dc026fa01ae26822bfb23f98e725444d6775b0",
"protocol": "0.7.2"
},
"nonce": 1455216323786,
"signature": "904502207e8a439f2cb33055e0b2e2d90e775f29d90b3ad85aec0c..."
},
"id": "7b6a2ab35da6826995abf3310a4875097df88cdb"
}
```

Upon receipt of the response, the renting node, must update it's local record
of the storage contract once more, to include the updated signature from the
farming node. Once this exchange is completed, the contract has been
successfully transferred and/or renewed.


Loading

0 comments on commit 3ae16d9

Please sign in to comment.