Perun-node

Introduction

Perun-node is a multi-user node software intended to facilitate users to open, transact on and settle state channels. It uses the go-perun SDK for running the perun protocol and implements the other functionalities (described in the following section) on top of that. The first implementation is done in golang and currently supports payment channels. Running an instance of perun-node will start an API server that acts as an interface for the user to interact with the node.

Functionalities

Off-Chain Identity Management

Enable the user to identify participants in the off-chain network by using an identity provider service. Currently, we have implemented a local identity provider by storing a list of known participants and their identities in a file on the disk. An alias is assigned to each participant and these aliases are unique within an instance of identity provider. The aliases are used by the user to refer to participants in API calls to the node.

Key Management

Enable the user to manage his cryptographic keys used for signing on-chain transactions and off-chain messages. Currently we have implemented support for ethereum keystore.

Session

Provide an environment for the user to access his ID provider, key manager and all the channels opened within this session. In the context of a session, he/she can open a state channel, do some transactions on the channels and settle it. Each session runs its own instance of state channel network client, ID provider, key manager; and hence provides a complete isolated environment within the node. It is this feature that enables multiple users to use the same node by having dedicated sessions for each of them.

User need not be worried about losing his/her data when a sudden closure of session occurs due to some network error or because of some other reasons. All the data within the sessions are continuously persisted. User can reopen the session at any time and the last known state of the session will be restored. User also has the option to close a session that has open channels by using force option. In this case as well, the session data is persisted and restored when the session is reopened.

User API

Provide an interface for the user to interact with the node. The UserAPI consists of three category of methods: Node, Session and Channel to access the respective functionalities. Currently, we implement two party payment channel API for ethereum blockchain using gRPC protocol. It can be used for opening a payment channel where they can send or receive payments, finalize the channels on the blockchain, settle it and withdraw the funds back to the user’s account.

Starting the perun-node will run a gRPC server for communication. Complete specification of the payment channel API served by the perun-node can be found [here](https://github.com/hyperledger-labs/perun-proposals/blob/master/design/001-RPC-Interface-Specification.md).

Perun-node cli

Perun-node cli is a single user software with an interactive command line interface to connect with and use a running instance of perun-node. It is an independent module that uses gRPC client stubs generated from the API specification to interact with perun-node and does not share any code with other components.

For steps to try out the perun state channels using perun-node and perun-node cli, see the User guide section.

Releases

Current version is v0.5.0.

We have made 5 development releases so far. Of these v0.1.0 & v0.2.0 are legacy versions, developed under the project name ‘dst-go’, source code of which can be found in legacy/master of perun-node repo.

Details on the new features and improvements included in each release can be found in the releases section of perun-node repository.

User guide

Deployment environment

The below diagram shows the environment in which perun-node will be deployed.

Image not available

In a test environment, the artifacts for setting up a contacts provider and wallet provider can be generated using the perun-node software itself. But it is up to the user to set up a blockchain node. Recommended way for trying out is to use a ganache-cli node.

Pre-requisites

To use the perun-node, the following pre-requisites need to be met.

  1. Linux operating system

  2. Go (v1.14 or later)

    1. A running instance of ganache-cli (v6.9.1 or later) or

    2. A local blockchain network started using geth node or

    3. A connection to the ropsten testnet.

Note

If using ropsten testnet, user should have keys corresponding to accounts funded on the testnet and needs to follow additional steps when generating configuration artifacts.

Note

For the code blocks that appear in the following sections, if they are prefixed by

  • $, execute them in terminal,

  • >, execute them in perun-node cli.

Getting started

  1. Start a blockchain network using ganache-cli node. The two accounts in the command correspond to accounts that will be used in default configuration artifacts that will be generated in a later steps. Both these accounts are funded with 10 ETH each.

$ ganache-cli -b 1 --account="0x1fedd636dbc7e8d41a0622a2040b86fea8842cef9d4aa4c582aad00465b7acff,100000000000000000000" --account="0xb0309c60b4622d3071fad3e16c2ce4d0b1e7758316c187754f4dd0cfb44ceb33,100000000000000000000"
  1. Open a terminal, clone the project repository and switch into the project directory.

$ git clone https://github.com/hyperledger-labs/perun-node.git
$ cd perun-node
  1. Run the tests.

$ go tests -tags=integration -count=1 -p 1 ./...
  1. Build the project. This will generate two binaries: perunnode and perunnode-cli.

$ cd perun-node && make

Initializing the perun-node

To start a perun-node, user needs an ID provider, wallet provider, blockchain node and a configuration file. These artifacts and the order in which they have to be set up is shown in the below diagram.

Image not available
  1. The blockchain node was setup in step 1 and the perun-node binary was generated in step 4 of the Getting started. To generate the remaining artifacts, run the below command:

$ ./perunnode generate

This will generate the node and session artifacts:

  • Node: node.yaml file.

  • Session: Two directories (alice and bob) each containing session.yaml file, idprovider.yaml file and keystore directory with keys corresponding to the on-chain and off-chain accounts.

When using ganache-cli node with command mentioned in Getting started, these files can be used as such. The contracts addresses are pre-computed based on the account address and will be deployed on the ganache-cli node in a later step.

When using ropsten testnet, follow the steps mentioned in this (Optional) Connecting to ropsten testnet section before proceeding further.

  1. Run the below command to start the perun-node.

$ ./perunnode run

This will start the perunnode using the config file located at default path ./node.yaml that was generated in the previous step. If the perun-node was started successfully, the node configuration will be printed as shown below along with the text Serving... at the end. Leave the node running in this terminal. If log file is set to empty string, logs will be printed in this terminal.

$ ./perunnode run
Using node config file - node.yaml
Running perun node with the below config:
{LogLevel:             "debug",
 LogFile:              "",
 ChainURL:             "ws://127.0.0.1:8545",
 Adjudicator:          "0x9daEdAcb21dce86Af8604Ba1A1D7F9BFE55ddd63",
 Asset:                "0x5992089d61cE79B6CF90506F70DD42B8E42FB21d",
 ChainConnTimeout:     10s,
 OnChainTxTimeout:     1m0s,
 ResponseTimeout:      10s,
 CommTypes:            ["tcp"],
 IDProviderTypes:      ["local"],
 CurrencyInterpreters: ["ETH"]}.

Serving payment channel API via grpc at port :50001

(Optional) Connecting to ropsten testnet

  1. Start an instance of geth node or use an external service to connect with rospten testnet. In all case, update the URL (use websockets protocol for connection and not http) in the configuration files node.yaml, alice/session.yaml and bob/session.yaml.

  2. The contracts for perun-node v0.5.0 are deployed on the testnet in the following addresses: adjudicator (0x7dd2c7d72aAADaE2467b429920d2df88798CCda4) and ETH asset holder (0x30241b890b0c1A2d9B6Ce3D172020647C94E2AFa). Updated these addresses in all three config files.

  3. Create two accounts, once each for alice and bob. Fund these accounts with a few ethers by requesting from faucet. Update the keys and address of the created accounts in the session config files.

Initializing perunnode-cli

  1. Open two new terminals side by side, one each for alice and bob roles respectively. In each of the terminals, start the perunnode-cli app using below command to start an interactive shell.

$ ./perunnodecli

Note

To see a complete list of commands, type help. To see the list of sub-commands for each command, type the command without any arguemnts and hit enter.

All commands and sub commands support autocompletion.

  1. Set the blockchain address. This address will be used by the sub-commands of chain command.

> chain set-blockchain-address ws://127.0.0.1:8545

Note

The chain command is not a part of perun-node API. It is a helper command in perun-node cli to directly interact with blockchain. We will be using it in the tutorial to read on-chain balances and deploy contracts.

  1. (Optional step, required only when using ganache-cli node) Deploy perun contracts.

> # [In Alice's CLI]
> chain deploy-perun-contracts
  1. Read the on-chain balance. The addresses for default configuration are available as auto-complete suggestion, if some other address was used, it needs to be entered manually.

> # [In Alice's CLI]
> chain get-on-chain-balance 0x8450c0055cB180C7C37A25866132A740b812937B

> chain get-on-chain-balance 0xc4bA4815c82727554e4c12A07a139b74c6742322

You can use these commands at any time before opening, while open or after closing a payment channel.

Open a session; open, use and close a payment channel

From here on, choose one terminal for alice role and one for bob role. In each step, a comment about the command will contain the role. If no role is mentioned above a command, it can be typed into any of the terminals.

  1. Open a session each for Alice and Bob. Also check if the other participant’s peer IDs are registered.

> # [In Alice's CLI]
> node connect :50001
> session open alice/session.yaml
> peer-id get bob
> # [In Bob's CLI]
> node connect :50001
> session open bob/session.yaml
> peer-id get alice

Note

Getting the peer ID will also add the peer alias to auto-completion list. When you press TAB after the sub-commands of channel, payment command that expect peer alias as the first argument, these aliases will be suggested.

  1. Send a payment channel opening request and accept it.

  1. Alice sends a payment channel opening request to Bob.

> # [In Alice's CLI]
> channel send-opening-request bob 1 2
  1. Bob receives a notification in his CLI. The incoming request contains a request ID.

> # [In Bob's CLI]
> Channel opening request notification received. Notification Alias: request_1_alice.
Currency: ETH, Balance: [alice:1.000000 self:1.000000].
Expires in 10s.

Note

Request ID is an identifier assigned by perun-node cli application to reference the request when accepting/rejecting it.

  1. Bob accepts the request before it expires.

> # [In Bob's CLI]
> channel accept-opening-request request_1_alice
  1. Once Bob accepts the request, the channel will be funded on-chain. Once it is opened, both Alice and Bob receive notifications in their CLIs.

> # [In Alice's CLI]
> Channel opened. Alias: ch_1_bob.
ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f, Currency: ETH, Version: 0, Balance [bob:1.000000 self:1.000000].

Subscribed to payment notifications on channel ch_1_bob (ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f)
> # [In Bob's CLI]
> Channel opened. Alias: ch_1_alice.
ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f, Currency: ETH, Version: 0, Balance [alice:1.000000 self:1.000000]

Subscribed to payment notifications on channel ch_1_bob (ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f)

Note

Channel alias is an identifier assigned by perun-node cli application to reference the channel when sending/receiving payments or closing it. It will be different for alice and bob, as it local to the perun-node cli instance.

In this case, it is ch_1_bob for Alice and ch_1_alice for Bob.

  1. List all the open channels in a session along with their latest state.

> channel list-open-channels
  1. Send a payment channel opening request and reject it.

Repeat sections (a) and (b) as in the step 2. This time, the request ID will be different: request_alice_2. Instead of accepting the request, reject it.

  1. Bob rejects the request before it expires.

> # [In Bob's CLI]
> channel reject-opening-request request_2_alice
  1. After the channel is rejected, Bob will get the following response.

> Channel proposal rejected successfully.
  1. And, Alice will get the following response.

> Error opening channel : The request was rejected by peer
  1. Send a payment on the open channel and accept it.

  1. Alice sends a payment to bob on the open channel (ch_1_bob).

> # [In Alice's CLI]
> payment send-to-peer ch_1_bob 0.1
  1. Bob receives a notification. Note that, the proposed version is different from the current version.

> # [In Bob's CLI]
> Payment notification received on channel ch_1_alice. (ID:94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f)
Current:        Currency: ETH, Balance: [alice:1.000000 self:1.000000], Version: 0.
Proposed:       Currency: ETH, Balance: [alice:0.900000 self:1.100000], Version: 1.
Expires in 10s.
  1. Bob accepts the payment.

> # [In Bob's CLI]
> payment accept-payment-update-from-peer ch_1_alice
  1. Once the payment is accepted, both Alice and Bob receive channel update notifications.

> # [In Alice's CLI]
> Payment sent to peer on channel ch_1_bob. Updated channel Info:
ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f, Currency: ETH, Version: 1, Balance [bob:1.100000 self:0.900000].
> # [In Bob's CLI]
> Payment channel updated. Alias: ch_1_alice. Updated Info:
ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f, Currency: ETH, Version: 1, Balance [alice:0.900000 self:1.100000]
  1. Send a payment on the open channel and reject it.

Repeat sections (a) and (b) as in the above command. This time the current and proposed versions will be different. Instead of accepting the channel, reject it.

  1. Bob rejects the payment from Alice.

> # [In Bob's CLI]
> payment reject-payment-update-from-peer ch_1_bob
  1. Once the payment is rejected, Bob will get the following response.

> # [In Bob's CLI]
> Payment channel update rejected successfully.
  1. And Alice will get the following response.

> # [In Alice's CLI]
> Error sending payment to peer: The request was rejected by peer.
  1. Error on closing a session with open channels without force option.

    Closing a session with open channels without force option should return an error. It is not safe to do so because, the node will not be able to refute if the other participant registers and finalizes an older state on the blockchain.

> session close no-force
> Error closing session : Session cannot be closed (without force option) as there are open channels
  1. Close the channel.

a. Alice sends a request to close the channel. Perun-node will send a channel update to Bob, marking the latest state as final.

> # [In Alice's CLI]
> channel close-n-settle-on-chain ch_1_bob

Note

Collaborative and Non collaborative channel close:

When any one of the channel participant sends a channel close request to the perun-node, an update is send to other participants marking the latest state of the channel as final.

If this update is accepted by the peer, then this is called finalized state. A finalized state can be registered on the blockchain in a single transaction and the funds can be withdrawn immediately. This is called Collaborative close.

If this update is rejected by the peer, then the latest state of channel is registered on the blockchain and both parties will have to wait for the challenge duration to pass. Once it passes, the state should be concluded on the blockchain and then the paricipants can withdraw their funds. This is called Non collaborative close.

  1. Bob gets a finalizing channel update.

> # [In Bob's CLI]
> Finalizing payment notification received on channel ch_1_alice. (ID:94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f)
Channel will closed if this payment update is responded to.
Current:        Currency: ETH, Balance: [alice:0.900000 self:1.100000], Version: 1.
Proposed:       Currency: ETH, Balance: [alice:0.900000 self:1.100000], Version: 2.
Expires in 10s.
  1. Bob accepts the notification, thereby enabling collaborative close.

> # [In Bob's CLI]
> payment accept-payment-update-from-peer ch_1_alice
  1. Once Bob accepts the update, he gets the following response. In the background, finalized state will be registered on the blockchain.

> # [In Bob's CLI]
> Payment channel updated. Alias: ch_1_alice. Updated Info:
ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f, Currency: ETH, Version: 2, Balance [alice:0.900000 self:1.100000]
  1. Once the finalized state is registered on the blockchain, funds will be withdrawn for both the participants. Both Alice and Bob will receive channel close notifications.

> # [In Alice's CLI]
> Payment channel close notification received on channel ch_1_bob (ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f)
Currency: ETH, Balance: [bob:1.100000 self:0.900000], Version: 2.
> # [In Bob's CLI]
> Payment channel close notification received on channel ch_1_alice (ID: 94241c75d058186f40826be7ae0803f7731a423903c494faa05b347443bb0a4f)
Currency: ETH, Balance: [alice:0.900000 self:1.100000], Version: 2.
  1. Close the session:

Since the open channels are closed, the session can be closed with the same command as in step 6. This should return a success response as shown below.

> # [In Alice's CLI]
> session close no-force

> # [In Bob's CLI]
> session close no-force
  1. Try out persistence of channels:

  1. Open a session each for alice and bob by following step 1. Then open a few channels by following step 2. Now close the session for alice and bob with force option.

> # [In Alice's CLI]
> session close force

> # [In Bob's CLI]
> session close force
  1. Now, in the same or different instances of CLI, open the sessions for alice and bob specifying the same configuration file. The session will be opened, channels restored from persistence and their latest state along with the aliases will be printed. Now, you can send/receive payments on these channels and close them.

Remarks:

  1. You can try to open as many channels as desired using the commands as described in step 2. Each channel is addressed by its alias (that will be suggested in auto-complete).

  2. You can also try and send as many payments as desired using the commands as described in step 4. However, whenever a new payment notification is received, the previous one is automatically dropped. This however, is not a feature of payment channel API, where you can respond to any of the notifications as long as they have not expired. It was just a feature in the perunnode-cli app to make it simpler.

  3. The purpose of the perunnode-cli software is to demo the payment channel API and also as a reference implementation for using the gRPC client stubs. In order to integrate the client for perun-node with your application, you can generate the gRPC client stubs in the desired language and directly use them in your application.