Release Notes - RNode v0.7

Information on breaking changes and significant new features released with RNode version 0.7.

Validator bonding to support the proof of stake (PoS) consensus system is now available.

The RChain platform has a pure proof of stake of consensus system. To secure the network, validators must provide a bond, which is 'locked' into the PoS contract on the chain. We call this process validator bonding. During the test net phase of the project there is no way to acquire tokens for the network. So to support validator bonding, this version of RNode offers a faucet to dispense the bond amount. To start the validator bonding process users invoke the 'GenerateBondingDeploys' client api. They provide a public/private key pair and bond amount through this api to generate the Rholang files required to create the bonding request.

For new validators to bond, a network must have at least 1 bonded validator at Genesis. The bonding request must be sent to this bonded validator. To properly bond to the network, a node should join the network as a validating node would (include the private key at start) and then obtain the state of the network from other nodes. This is also referred to as 'Read Only Mode'. The bonding requests (deploys) need to be sent to a bonded validator by specifying the '--grpc-host' option and passing in the bonded validators' IP address. The bonded validator should propose blocks to finalize the bonding requests. Once the prospective validating node has an updated version of the PoS contract containing the its validator identity and bond amount, the node considers itself bonded. After this point, the node can propose blocks.

Genesis validators will acquire their bond out of protocol, and will be bonded at the launch of main net.  After Genesis, prospective validators will have to acquire Rev token on the chain in order to bond.

A name registry is now available.

The name registry provides secure, efficient storage of Rholang terms. Unforgeable names can be registered arbitrarily, and any other term can be registered using a public key and a signature as proof of ownership. All entries are referenced by URI.


new insertArbitrary(`rho:registry:insertArbitrary`) in { … }
new insertSigned_ed25519(`rho:registry:insertSigned:ed25519`) in { … }
new lookup(`rho:registry:lookup`) in { … }


// insertArbitrary
//     Insert an unforgable name
//     Two parameters: name, returnUri
new insertArbitrary(`rho:registry:insertArbitrary`), stdout(`rho:io:stdout`) in {
    new x, return in {
        // Insert the name into the registry
        // Wrap in bundle+ so only write is possible for those who lookup
        insertArbitrary!(bundle+{*x}, *return) |

        // Receive the URI generated by the registry
        for (xUri <- return) {
            // Something like: `rho:id:rtu77e1cj1ky7dpqyoc6o8rcdseseax35qi7w37hbf3astmrcupusi`

// insertSigned 
//     Insert a signed term using ed25519 signature 
//     Four parameters: public-key, term, signature, returnUri 
new insertSigned_ed25519(`rho:registry:insertSigned:ed25519`), stdout(`rho:io:stdout`) in {
    new return in {
        // Secret key:
        // d039d5c634ad95d968fc18368d81b97aaecd32fc7cf6eec07a97c5ac9f9fcb5b11afb9a5fa2b3e194b701987b3531a93dbdf790dac26f8a2502cfa5d529f6b4d
        // Public key:
        // 11afb9a5fa2b3e194b701987b3531a93dbdf790dac26f8a2502cfa5d529f6b4d
        // The signatures here are over the serialized representation of the nonce, value tuple.
        // To recreate the signatures, you can do something like the following:
        // val key = Base16.decode("<secret key goes here>")
        // val toSign: Par = ETuple(Seq(GInt(789), GString("entry")))
        // val sig = Ed25519.sign(toSign.toByteArray, key)
            (789, "entry"),
            *return) |
        // Receive the URI generated by the registry
        for (entryUri <- return) {

// lookup
//     Look up an entry in the registry 
//     Two parameters: uri, return 
new lookup(`rho:registry:lookup`),
    stdout(`rho:io:stdout`) in {

    // Part 1, Run this code once and then comment it out
    // /*
    new x, insertReturn in {
        // Insert x into the registry
         insertArbitrary!(bundle+{*x}, *insertReturn) |

         // Receive the URI returned from the registry
         for (xUri <- insertReturn) {
            // Write out the URI generated by the registry
            // (A) REMEMBER THIS VALUE, use it below
        } |

        // Set up a receive on x
        for (v <= x) {
            stdout!("Received from x") |

    // End of Part 1, after running once, comment out to here
    // */

    // Part 2, Uncomment this code once you've run Part 1 first
    new lookupReturn in {
        // Lookup x using its URI from location (A) above
        // lookup!(`The Value from A`, *lookupReturn) |

        // x is returned, calling it xFromRegistry here
        for (xFromRegistry <- lookupReturn) {
            // Send on the name retrieved from the registry (which is really x)
            xFromRegistry!("Hello, I'm sending on x which I got from the registry.")
    // End of Part 2

The use of logical connectives AND, OR, and NOT in consumes has changed.

Starting with this version (RNode 0.7), only the logical connective AND ('/\') is allowed in consumes ('contract' and 'for' expressions). The cost accounting system requires that pattern matching operations consume negligible resources. Using the logical connectives OR ('\/') or NOT ('~') could produce expressions which would be costly to perform even though a match would not be made, and thus, would not be charged for execution. This introduces an attack vector against validators. Multiple mitigations were considered which sought to retain as much expressiveness in the language as possible, while addressing the costing issue. The solution chosen was to change the Rholang grammar to only accept the AND ('/\') logical connective in consumes. Note that the OR ('\/') and NOT ('~') are still valid within 'match' expressions. This change only affects consumes ('contract' and 'for' expressions).


new x in {
    // ERROR: logical OR is used in the pattern of the receive
    for(@{Nil \/ Nil} <- x) { Nil }

new x in {
    // ERROR: logical NOT is used in the pattern of the receive
    for(@{~Nil} <- x) { Nil }

new x in {
    // OK: logical AND is allowed in the receive
    for(@{Nil /\ Nil} <- x) { Nil }

The RNode version number and Git hash can now be retrieved from a remote node.

$ curl -s localhost:40403/version

The show-blocks feature has changed to return only header information and a new depth parameter was added to specify how many blocks, measured from the current block, to display.

$ rnode show-blocks -d 10

Shards can be configured to enforce minimum and maximum bonding amounts. The root shard bond amounts are configured to a minimum of 1,500 Rev and a maximum of 1,000,000 Rev.

$ rnode run --minimum-bond 1000 --maximum-bond 100000

Deploy command now requires the payment parameters purse address, phlo limit, phlo price, and a nonce, as well as the previously required Rholang file name.

Subcommand: deploy - Deploy a Rholang source file to Casper on an existing running node. The deploy will be packaged and sent as a block to the network 
depending on the configuration of the Casper instance.

-f, --from <arg> Purse address that will be used to pay for the deployment.
-n, --nonce <arg> This allows you to overwrite your own pending transactions that use the same nonce.
-p, --phlo-limit <arg> The amount of phlo to use for the transaction (unused phlo is refunded). Must be positive integer.
--phlo-price <arg> The price of phlo for this transaction in units dust/phlo. Must be positive integer.

Listening on a name now takes in a starting block height and ending block height.

Subcommand: listen-data-at-name - Listen for data at the specified name

-c, --content <arg> Rholang name
-t, --type <arg> Type of the specified name

Subcommand: listen-cont-at-name - Listen for continuation at the specified name

-c, --content <arg> Rholang name
-t, --type <arg> Type of the specified name

The internal representation of Rholang terms has changed.

The Channel type has been removed. Channels are now represented by just a Par which is assumed to be quoted. This change will affect clients using the gRPC API to consume protobufs or signing terms which would have used the Channel type.

There is no content with the specified labels