Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This is an in-progress document started by Michael Birch (Unlicensed) which represents describes what the Rchain state is and how it is represented in the blockchain. This document ignores any details related to namespaces/sharding. This document embeds 3 options related to gas payments: 1) "Ethereum clone", 2) "Abstracted Gas Payment", and 3) "Free Market". Most of the text applies to all options: there will be a section under each header if there are differences between the options. 

The RChain state is a giant Rholang term: mostly top-level contracts that are parred together, i.e., contract foo {...} | contract bar {...} | contract baz {...} | ... | contract zzz {...}. The Rchain state will be replicated and updated through the Rchain blockchain. The genesis block contains this term explicitly, while future blocks only contain changes to this term and the hash of the complete term. Changes are inserted to this term through Deployments, which in turn will trigger communication (Comm) events (modeling the pi calculus construct where an input meets an output). Ignoring gas cost details, a Deployment officially terminates when no more Comm events are triggered. The  The post-state of a block is the state is obtained from the state when all Deployments that were included in that block have terminatedparent post-state by "parring-in" the new deployments and applying the subsequent comm. events (both of which are given in the block). Term normalization, the VM transition rules, and a log of Deployments and Comm events will help the Casper consensus protocol to produce a post-state of a block that is consistent across nodes.

...

The block consists of three different tries: the Deployment root, the Comm event root, and the state root. These roughly correspond respectively to the Ethereum transaction root, receipts root, and state root. The state root trie is a giant key value store that maps names/channels to a tuple of continuations and lists of data (see the Storage Specification for details); i.e. it is the tuplespace. The block header includes a list of parent block hashes. The transactions in the parent blocks must not conflict with one another.

Structure of a Deployment

The Deployment is what would normally be considered a "transaction" in the blockchain space. It has  has the unserialized format Deploy(<code>, <other><wallet details>, <rev/phlo conversion rate>) where <code> is a valid Rchain process. In addition, all Deployments must have a unique <code> hashRholang process. Let S be the current Rchain state, at the start of applying a Deploy operation, the state will be S' = S | <code>. Then Comm events are processed in S', until no further reductions are possible (quiescence). The final state after the Deploy operation, S'', is the state which is reached when there are no further Comm events quiescent state (i.e. all inputs/outputs are waiting for their corresponding outputs/inputs). Note that, due to the concurrent nature of Rholang, multiple Deployments could be processed at the same time.

Specific to option (1): Paying gas up front Ethereum style

<other> consists of <paying_account>, <seq>, <sig>, <token/gas conversion>, <gas limit>

<paying_account> specifies the account to do the gas purchase from; specifically, the <token/gas conversion>*<gas limit> tokens will be decremented from the hash of the <paying_account> from the rev balance map.

<seq> and <sig> are, as in Ethereum, to validate that someone with the right public key is authorizing the transaction and to not allow replay attacks. We could consider delegating this check to a contract, rather than external in the protocol, or to abstract it away as an arbitrary withdraw condition with general <evidence> given to <paying_account> to validate.

Note we assumed above the token will be REV, but we can also inject a field <token_address> to abstract which token we will be decrementing the gas costs from.

Specific to option (2) and (3): Abstracting gas payments/"Free Market"

<other> is blank. All signature and gas details go inside of the <code>The details of payment for computation will be in another document (link? Joseph Denman).

Retrieving the Rchain State

...

Payment for any system-related operations (e.g. buying gas, bonding to be come a validator in Capser) must be done by providing an object with the right capabilities as an argument to the cal (i.e. if withdraw from that purse needs to happen then it must expose getDecr, but if only depositing in needing, as in PoS unbonding, then a forwarder with deposit exposed is sufficient). Therefore, it will be important to have a standardized API so that we can be agnostic about the specific objects which are actually be passed as arguments (purses or forwarders). However, the important note is that all "accounts" are actually purse instances or contracts wrapping purse instances. Ideally all payments would be parametric in the mint used, but perhaps initially only Rev purses/forwarders will be accepted.

...

PoS Blessed Contract

This privileged proof-of-stake contract must perform the following functions.

  1. Maintain a separate account registry which can be read by client software to learn the identities and staked amount for all validators
  2. Accept “bonds” from user accounts and use them to create new validator accounts
  3. Accept “unbond” messages which delete the validator account and restore its bond to the original user
  4. Handle slashing. Anyone can be a slasher. The slasher must submit objective evidence of an offence: we don't want some malicious cartel of validators arbitrarily trying to take out their competition. To be effective, the offender’s stake must still be held hostage. To prevent a DOS attack, the slasher must also pay a fee for attempting to slash. The casper contract verifies the evidence and if the evidence is valid, the offender loses a portion of their stake. What the slashing conditions are and what constitutes objective evidence for them needs to be worked out. This could be tied in with the notion of “valid” blocks/state transitions mentioned as a function of the client software (off chain) by saying that creating an invalid block is one of the slashing conditions, with the evidence being a signed message from the offender sending such a block. Even if this is done, the default client software (distributed by the RChain Coop) should still only allow valid blocks to be received in order to mitigate damage an invalid block might do to the network before the creator is slashed.
  5. Distributes rewards e.g. through distributing transaction fees (and maybe interest) to the balance of validator accounts
    1. Let

      tx_fee = transaction fees in the block
      step_parent_discount = constant less than 1
      tx_step_parents = sum of transaction fees for all included step_parent blocks
      proposing_discount = function of number of blocks you have mined in the past where more recent blocks factor in more heavily
      few_transactions_penalty = function of tx_fee such that once the tx_fee is high enough, this value is 0

      We have

      my reward = proposing_discount*(tx_fee - step_parent_discount*tx_step_parents - few_transactions_penalty)
      step_parent reward = step_parent_discount*tx_step_parent

Details of these functions are given on the  Details of Proof-of-Stake in RChain page.

The bonding/unbonding processes must have rules which are coded into the contract. For example, rate limiting bonding to prevent the “army of ants” attack. Note that this is all which is required by the on-chain Casper contract (which is why calling it a proof-of-stake contract would be more accurate)PoS contract, while client software would need to handle software written in scala handles the remaining tasks:

  • listening for new blocks (or new state change requests for validators); i.e. networking stuff
  • only accepting valid changes/blocks (r.f. Above note about arbitrary parring; also ignoring malformed messages; and perhaps something about forced comm. events to mitigate censorship)
  • decided current head block based on received information and some fork-choice rule (which should somehow use the stake balances that are inside the PoS contract’s state)
  • deduce and store current state based on transactions which have been received; i.e. storage layer and VM layer stuff

The Registry Blessed Contract

Rholang allows sending and receiving data on any name, including  quoted processes such as @"Hello World!". This is an important feature, as it allows for exressive ways of defining class-like "objects" (see examples on GitHub), however could also lead to unwanted behaviour if contracts are specified at names which do not contain any unforgable part (e.g. phishing, itercepting calls intended for another contract). Therefore, the blockchain runtime for Rholang will have a special set of reserved names for which sending/receiving privliges must be obtained via a registry contract. Names of the form @`rho:...` (i.e. quoted URIs starting with "rho:") will not be able to be used for sending/receiving by default. There are three categories of these sorts of names that can be registered:

  • Code body hashes: e.g. rho:hash:sha256:... – requires submitted code body to match hash in URI
  • Public keys: e.g. rho:pubkey:secp256:... – requires proof of ownsership via a signature
  • Externally owned domain names: e.g. rho:iana:.. – requires proof of ownerhship via usual domain name methods