Skip to content

Commit

Permalink
Adding support for immutable ledger for transactions. New nodes can n…
Browse files Browse the repository at this point in the history
…ow be added using transactions. Node regsitry can be build using a transaction file. Orientdb can be used as secondary storage, it can now support merkle tree for persistence. Also adding some abstractions over orientdb for using it as a graph store
  • Loading branch information
lovesh committed May 9, 2016
1 parent a786dc9 commit 7b696e1
Show file tree
Hide file tree
Showing 128 changed files with 3,762 additions and 1,159 deletions.
6 changes: 6 additions & 0 deletions .eggs/README.txt
@@ -0,0 +1,6 @@
This directory contains eggs that were downloaded by setuptools to build, test, and run plug-ins.

This directory caches those eggs to prevent repeated downloads.

However, it is safe to delete this directory.

1 change: 1 addition & 0 deletions MANIFEST.in
@@ -0,0 +1 @@
recursive-include data *
59 changes: 59 additions & 0 deletions README.md
Expand Up @@ -90,6 +90,8 @@ sudo apt-get update
sudo apt-get install libsodium13
```

8. If you still get the error ```E: Unable to locate package libsodium13``` then add ```deb http://ppa.launchpad.net/chris-lea/libsodium/ubuntu trusty main``` and ```deb-src http://ppa.launchpad.net/chris-lea/libsodium/ubuntu trusty main``` to your ```/etc/apt/sources.list```.
Now run ```sudo apt-get update``` and then ```sudo apt-get install libsodium13```

**CentOS/Redhat:**

Expand Down Expand Up @@ -123,6 +125,7 @@ sudo apt-get install libsodium13

5. Download the latest build (pywin32-220.win-amd64-py3.5.exe is the latest build as of this writing) from [here](https://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/) and run the downloaded executable.


### Using a virtual environment (recommended)
We recommend creating a new Python virtual environment for trying out Plenum.
a virtual environment is a Python environment which is isolated from the
Expand All @@ -137,3 +140,59 @@ And activate it by:
```
source <name of virtual environment>/bin/activate
```


### Initializing Keep
```
init_plenum_raet_keep --name Alpha --seeds 000000000000000000000000000Alpha Alpha000000000000000000000000000 --force
```

```
init_plenum_raet_keep --name Beta --seeds 0000000000000000000000000000Beta Beta0000000000000000000000000000 --force
```

```
init_plenum_raet_keep --name Gamma --seeds 000000000000000000000000000Gamma Gamma000000000000000000000000000 --force
```

```
init_plenum_raet_keep --name Delta --seeds 000000000000000000000000000Delta Delta000000000000000000000000000 --force
```
Note: Seed can be any randomly chosen 32 byte value. It does not have to be in the format `00..<name of the node>`.


### Seeds used for generating clients
1. Seed used for steward Bob's signing key pair ```11111111111111111111111111111111```
2. Seed used for steward Bob's public private key pair ```33333333333333333333333333333333```
3. Seed used for client Alice's signing key pair ```22222222222222222222222222222222```
4. Seed used for client Alice's public private key pair ```44444444444444444444444444444444```


### Running Node

```
start_plenum_node Alpha
```


### Updating configuration
To update any configuration parameters, you need to update the `plenum_config.py` in `.plenum` directory inside your home directory.
eg. To update the node registry to use `127.0.0.1` as host put these in your `plenum_config.py`.

```python
from collections import OrderedDict

nodeReg = OrderedDict([
('Alpha', (('127.0.0.1', 9701), '0490a246940fa636235c664b8e767f2a79e48899324c607d73241e11e558bbd7', 'ea95ae1c913b59b7470443d79a6578c1b0d6e1cad0471d10cee783dbf9fda655')),
('Beta', (('127.0.0.1', 9703), 'b628de8ac1198031bd1dba3ab38077690ca9a65aa18aec615865578af309b3fb', '18833482f6625d9bc788310fe390d44dd268427003f9fd91534e7c382501cd3c')),
('Gamma', (('127.0.0.1', 9705), '92d820f5eb394cfaa8d6e462f14708ddecbd4dbe0a388fbc7b5da1d85ce1c25a', 'b7e161743144814552e90dc3e1c11d37ee5a488f9b669de9b8617c4af69d566c')),
('Delta', (('127.0.0.1', 9707), '3af81a541097e3e042cacbe8761c0f9e54326049e1ceda38017c95c432312f6f', '8b112025d525c47e9df81a6de2966e1b4ee1ac239766e769f19d831175a04264'))
])

cliNodeReg = OrderedDict([
('AlphaC', (('127.0.0.1', 9702), '0490a246940fa636235c664b8e767f2a79e48899324c607d73241e11e558bbd7', 'ea95ae1c913b59b7470443d79a6578c1b0d6e1cad0471d10cee783dbf9fda655')),
('BetaC', (('127.0.0.1', 9704), 'b628de8ac1198031bd1dba3ab38077690ca9a65aa18aec615865578af309b3fb', '18833482f6625d9bc788310fe390d44dd268427003f9fd91534e7c382501cd3c')),
('GammaC', (('127.0.0.1', 9706), '92d820f5eb394cfaa8d6e462f14708ddecbd4dbe0a388fbc7b5da1d85ce1c25a', 'b7e161743144814552e90dc3e1c11d37ee5a488f9b669de9b8617c4af69d566c')),
('DeltaC', (('127.0.0.1', 9708), '3af81a541097e3e042cacbe8761c0f9e54326049e1ceda38017c95c432312f6f', '8b112025d525c47e9df81a6de2966e1b4ee1ac239766e769f19d831175a04264'))
])
```
1 change: 1 addition & 0 deletions data/__init__.py
@@ -0,0 +1 @@

7 changes: 7 additions & 0 deletions data/pool_transactions
@@ -0,0 +1,7 @@
{"txnId":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","type":"NEW_STEWARD","data":{"pubkey":"7b0d47d93427f8311160781c7c733fd89f88970aef490d8aa0ee19a4cb8a1b14","alias":"Bob"},"dest":"SAdaWX5yGhVuLgeZ3lzAxTJNxufq8c3UYlCGjsUyFd0="} dad3ecccd7e67342cb5afef36dc7b3298e51a7cd81299eb63def07e0f870d06e
{"txnId":"d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35","origin":"SAdaWX5yGhVuLgeZ3lzAxTJNxufq8c3UYlCGjsUyFd0=","type":"NEW_NODE","data":{"node_ip":"52.33.22.91","client_port":9702,"node_port":9701,"client_ip":"52.33.22.91","alias":"EvernymV1","pubkey":"ea95ae1c913b59b7470443d79a6578c1b0d6e1cad0471d10cee783dbf9fda655"},"dest":"BJCiRpQPpjYjXGZLjnZ/KnnkiJkyTGB9cyQeEeVYu9c="} c143ca2995fe6be13701645146eb74699a98867f961f9c8b9ab454c47eb7c839
{"txnId":"4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce","origin":"SAdaWX5yGhVuLgeZ3lzAxTJNxufq8c3UYlCGjsUyFd0=","type":"NEW_NODE","data":{"node_ip":"52.38.24.189","client_port":9704,"node_port":9703,"client_ip":"52.38.24.189","alias":"EvernymV2","pubkey":"18833482f6625d9bc788310fe390d44dd268427003f9fd91534e7c382501cd3c"},"dest":"tijeisEZgDG9Hbo6s4B3aQypplqhiuxhWGVXivMJs/s="} 92d18f0d628e78b5b0bf8aaa33e0729ac088ed6dd65a2dc81a02e200e63a0ea3
{"txnId":"4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a","origin":"SAdaWX5yGhVuLgeZ3lzAxTJNxufq8c3UYlCGjsUyFd0=","type":"NEW_NODE","data":{"node_ip":"13.93.218.255","client_port":9706,"node_port":9705,"client_ip":"13.93.218.255","alias":"WSECU","pubkey":"b7e161743144814552e90dc3e1c11d37ee5a488f9b669de9b8617c4af69d566c"},"dest":"ktgg9es5TPqo1uRi8UcI3ey9Tb4KOI+8e12h2Fzhwlo="} 8416d7327e2c9fe515cf09162b14a2e06245aeef198291daeae78e5970c04021
{"txnId":"ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d","origin":"SAdaWX5yGhVuLgeZ3lzAxTJNxufq8c3UYlCGjsUyFd0=","type":"NEW_NODE","data":{"node_ip":"52.160.103.164","client_port":9708,"node_port":9707,"client_ip":"52.160.103.164","alias":"BIG","pubkey":"8b112025d525c47e9df81a6de2966e1b4ee1ac239766e769f19d831175a04264"},"dest":"OvgaVBCX4+BCysvodhwPnlQyYEnhzto4AXyVxDIxL28="} 9b27e4f5d68d7aa631222e274b446c80f234ab40f9d2a1a84014c56569eac1c5
{"txnId":"ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39e","origin":"SAdaWX5yGhVuLgeZ3lzAxTJNxufq8c3UYlCGjsUyFd0=","type":"NEW_NODE","data":{"node_ip":"54.173.9.185","client_port":9710,"node_port":9709,"client_ip":"54.173.9.185","alias":"RespectNetwork","pubkey":"8a71e22b7a7f4816bd784656dfb6fa59d6c23aeb4847d5ea41bb179cf28ba606"},"dest":"Hi3t6Q6JWsCXUBVzy0d7IlMkHdRDDUtrkZxmQBgIDYc="} 9b27e4f5d68d7aa631222e274b446c80f234ab40f9d2a1a84014c56569eac1c5
{"txnId":"e7f6c011776e8db7cd330b54174fd76f7d0216b612387a5ffcfb81e6f0919683","origin":"SAdaWX5yGhVuLgeZ3lzAxTJNxufq8c3UYlCGjsUyFd0=","type":"NEW_CLIENT","data":{"pubkey":"ffc951aa6f2fa03096d1d1b579735b2f6f84019fe2f617aa65ff3d68705f2527","alias":"Alice"},"dest":"XiEsCYDks5/AlyETSqAhCTdO39JgwNPQPLUByNZUV6k="} 8a664770f67254b7de53596a6c19f1ea6f84069a61d54151d4bd519d7a2f2e21
68 changes: 68 additions & 0 deletions examples/new_client.py
@@ -0,0 +1,68 @@
#! /usr/bin/env python3
"""
This is a simple script to demonstrate a client connecting to a running
consensus pool. To see it in action, run simple_node.py in four separate
terminals, and in a fifth one, run this script.
TODO: create client
TODO: demonstrate client verification key bootstrapping
"""

#TODO Remove this file, just for now

import os
from collections import OrderedDict

from plenum.client.client import Client
from plenum.client.signer import SimpleSigner
from plenum.common.looper import Looper
from plenum.common.util import getConfig


def run_node():

with Looper(debug=False) as looper:
# Nodes persist keys when bootstrapping to other nodes and reconnecting
# using an ephemeral temporary directory when proving a concept is a
# nice way to keep things clean.
config = getConfig()
basedirpath = os.path.expanduser(config.baseDir)
cliNodeReg = {k: v[0] for k, v in config.cliNodeReg.items()}
clientName = 'Alice'

# this seed is used by the signer to deterministically generate
# a signature verification key that is shared out of band with the
# consensus pool
seed = b'22222222222222222222222222222222'
assert len(seed) == 32
signer = SimpleSigner(clientName, seed)

client_address = ('0.0.0.0', 9700)

client = Client(clientName,
cliNodeReg,
ha=client_address,
signer=signer,
basedirpath=basedirpath)
looper.add(client)

# give the client time to connect
looper.runFor(3)

# a simple message
msg = {'life_answer': 42}

# submit the request to the pool
request, = client.submit(msg)

# allow time for the request to be executed
looper.runFor(3)

reply, status = client.getReply(request.reqId)
print('')
print('Reply: {}\n'.format(reply))
print('Status: {}\n'.format(status))


if __name__ == '__main__':
run_node()
156 changes: 156 additions & 0 deletions examples/orientdb.py
@@ -0,0 +1,156 @@
import pyorient

client = pyorient.OrientDB("localhost", 2424)
dbName = "test"
user = "root"
password = "password"
session_id = client.connect(user, password)
client.db_drop(dbName, pyorient.STORAGE_TYPE_MEMORY)
client.db_create(dbName, pyorient.DB_TYPE_GRAPH, pyorient.STORAGE_TYPE_MEMORY)
# client.db_create(dbName, pyorient.DB_TYPE_GRAPH, pyorient.STORAGE_TYPE_PLOCAL)
client.db_exists(dbName, pyorient.STORAGE_TYPE_MEMORY)
client.db_list()
# Need to open the db for doing read/writes on it
client.db_open(dbName, user, password)

cmd1 = client.command("create class Animal extends V")

cmd2 = client.command("create vertex Animal set name = 'rat', specie = 'rodent'")

cmd3 = client.query("select * from Animal")

### Create the vertex and insert the food values

cmd4 = client.command('create class Food extends V')
cmd5 = client.command("create vertex Food set name = 'pea', color = 'green'")

### Create the edge for the Eat action
cmd6 = client.command('create class Eat extends E')

### Lets the rat likes to eat pea
eat_edges = client.command(
"create edge Eat from ("
"select from Animal where name = 'rat'"
") to ("
"select from Food where name = 'pea'"
")"
)

# Create edges using record id
eat_edges_1 = client.command("CREATE EDGE Eat FROM {} to {}".format(cmd3[0]._rid, cmd5[0]._rid))

### Who eats the peas?
pea_eaters = client.command("select expand( in( Eat )) from Food where name = 'pea'")
for animal in pea_eaters:
print(animal.name, animal.specie)
'rat rodent'

### What each animal eats?
animal_foods = client.command("select expand( out( Eat )) from Animal")
for food in animal_foods:
animal = client.query(
"select name from ( select expand( in('Eat') ) from Food where name = 'pea' )"
)[0]
print(food.name, food.color, animal.name)
'pea green rat'

client.command("CREATE CLASS Car EXTENDS V")
client.command("CREATE CLASS Owns EXTENDS E")
client.command("CREATE CLASS Person EXTENDS V")

client.command("CREATE VERTEX Person SET name = 'Luca'")
client.command("CREATE VERTEX Person SET name = 'Luca1'")
client.command("CREATE VERTEX Person SET name = 'Luca2'")

client.command("CREATE VERTEX Car SET name = 'Ferrari Modena'")
client.command("CREATE VERTEX Car SET name = 'Ferrari Modena1'")
client.command("CREATE VERTEX Car SET name = 'Ferrari Modena2'")

cmd7 = client.command("select * from Person where name = 'Luca1' limit 1")

cmd8 = client.command("select * from Person where name = 'Luca1'")

cmd9 = client.command("CREATE EDGE Owns FROM ( SELECT FROM Person where name = 'Luca1') TO ( SELECT FROM Car where name='Ferrari Modena2')")

client.command("create class auto extends V")
client.command("create property auto.name string")
client.command("create index auto.name unique")

client.command("create class rides extends E")
client.command("create property rides.out link Person")
client.command("create property rides.in link auto")

client.command("create class bike extends auto")
client.command("create class cycle extends auto")

client.command("create vertex bike SET name = 'bik1'")
client.command("create vertex bike SET name = 'bike2'")
client.command("create vertex cycle SET name = 'cycle1'")
client.command("create vertex cycle SET name = 'cycle2'")

b= client.command("select * from auto where name='bike2'")[0]
print(b._class)

client.command("create class cycler extends E")
client.command("create property cycler.out link Person")
client.command("create property cycler.in link cycle")
client.command("create edge cycler from ( SELECT FROM Person where name = 'Luca') TO ( SELECT FROM cycle where name='cycle1')")

# client.command("create edge cycler from ( SELECT FROM Person where name = 'Luca1') TO ( SELECT FROM Car where name='Ferrari Modena2')")

client.command("select expand (in('cycler')) from cycle where name = 'cycle1'")
client.command("select expand (in('cycler')) from cycle where name = 'cycle2'")

client.command("create edge rides from ( SELECT FROM Person where name = 'Luca1') TO ( SELECT FROM cycle where name='cycle1')")
client.command("create edge rides from ( SELECT FROM Person where name = 'Luca2') TO ( SELECT FROM bike where name='bike2')")

client.command("create class profile")
client.command("create property profile.id string")
client.command("create index profile.id unique")
client.command("insert into profile set name = 'Luca', age = 21, id = '1'")
client.command("update profile set name = 'Luca1' upsert where id = '1'")
client.command("update profile set name = 'Luca2' upsert where id = '2'")

client.command("create class Version")
client.command("create property Version.v string")
client.command("create property Version.release string")
client.command("create class Package")
client.command("create property Package.versions embeddedlist Version")

r = client.command('insert into Package set versions = [{"v":"1.0.1", "release":"monday"}]')
client.command('update %s add versions = [{"v":"1.0.2", "release":"tuesday"}]' % r[0]._rid)

cmd = (
# "begin;"
"create class Address;"
"create property Address.street String;"
"create property Address.city String;"
"create class Client;"
"create property Client.name String;"
"create property Client.phones embeddedSet String;"
"create property Client.addresses embeddedList Address;"
"insert into client set name = 'James Bond', phones = ['1234', '34567'], addresses = [{'city':'Shanghai', 'zip':'3999'}, {'city':'New York', 'street':'57th Ave'}];"
"update client add addresses = [{'city':'London', 'zip':'67373'}];"
# "commit;"
)

client.batch(cmd)
client.command("update Client add addresses = [{'city':'Delhi', 'zip':'2'}]")
client.command("select from Client")[0].oRecordData
client.command("update Client add addresses = {'city':'Mumbai', 'zip':'3'}")
client.command("select from Client")[0].oRecordData

cmd = (
"create class report;"
"create property report.id integer;"
"create property report.marks embeddedmap string;"
"insert into report set id = 1, marks={'p': 100, 'm': 'A', 'c': 2.4};"
)
client.batch(cmd)

client.command("select from report where marks[p] = 100")[0].oRecordData
client.command("select from report where marks.p = 100")[0].oRecordData

client.command("update report set marks.m = 'B' where id = 1")
client.command("update report set marks.b = 21 where id = 1")
client.command("update report set date = 1460128589.825324 return after $this.marks where id = 1")
8 changes: 5 additions & 3 deletions examples/simple_client.py
Expand Up @@ -7,12 +7,14 @@
TODO: create client
TODO: demonstrate client verification key bootstrapping
"""
import os
from collections import OrderedDict
from tempfile import TemporaryDirectory

from plenum.client.client import Client
from plenum.client.signer import SimpleSigner
from plenum.common.looper import Looper
from plenum.common.util import getConfig


def run_node():
Expand All @@ -28,20 +30,20 @@ def run_node():
# using an ephemeral temporary directory when proving a concept is a
# nice way to keep things clean.
with TemporaryDirectory() as tmpdir:
clientId = 'Joe'
clientName = 'Joe'

# this seed is used by the signer to deterministically generate
# a signature verification key that is shared out of band with the
# consensus pool
seed = b'a 32 byte super secret seed.....'
assert len(seed) == 32
signer = SimpleSigner(clientId, seed)
signer = SimpleSigner(clientName, seed)
assert signer.verkey == b'cffbb88a142be2f62d1b408818e21a2f' \
b'887c4442ae035a260d4cc2ec28ae24d6'

client_address = ('127.0.0.1', 8000)

client = Client(clientId,
client = Client(clientName,
cliNodeReg,
ha=client_address,
signer=signer,
Expand Down
8 changes: 4 additions & 4 deletions examples/simple_node.py
Expand Up @@ -20,10 +20,10 @@
def run_node():

nodeReg = OrderedDict([
('Alpha', ('127.0.0.1', 8001)),
('Beta', ('127.0.0.1', 8003)),
('Gamma', ('127.0.0.1', 8005)),
('Delta', ('127.0.0.1', 8007))])
('Alpha', ('127.0.0.1', 9701)),
('Beta', ('127.0.0.1', 9703)),
('Gamma', ('127.0.0.1', 9705)),
('Delta', ('127.0.0.1', 9707))])

# the first argument should be the node name
try:
Expand Down

0 comments on commit 7b696e1

Please sign in to comment.