Skip to content

Commit

Permalink
Merge pull request #1 from asonnino/master
Browse files Browse the repository at this point in the history
Java mock & multi node chainspace
  • Loading branch information
musalbas authored Jun 12, 2017
2 parents 84852d4 + a468e88 commit f02344f
Show file tree
Hide file tree
Showing 33 changed files with 805 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .idea/codeStyleSettings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/commons_logging_1_2.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/gson_2_6_2.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/httpclient_4_5_3.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/httpcore_4_4_6.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/json_20140107.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/json_simple_1_1_1.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/sqlite_jdbc_3_18_0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Chainspace

90 changes: 90 additions & 0 deletions bank_transfer_checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
##################################################################################
# Chainspace Mock
# bank_transfer_checker.py
#
# version: 0.0.1
##################################################################################
from __future__ import print_function # In python 2.7
import sys
from json import loads, dumps
from flask import Flask, request



##################################################################################
# checker
##################################################################################

# -------------------------------------------------------------------------------
# helper
# -------------------------------------------------------------------------------
def ccheck(V, msg):
if not V:
raise Exception(msg)

# -------------------------------------------------------------------------------
# checker
# -------------------------------------------------------------------------------
def checker_function(T):

print(T)

# check transfer's format
ccheck(T["contractMethod"] == r"http://127.0.0.1:5001/bank/transfer", "Wrong Method")
ccheck(len(T["referenceInputs"]) == 0, "Expect no references")

# retrieve inputs
from_account, to_account = T[u"inputs"]
amount = T[u"parameters"]["amount"]
from_account_new, to_account_new = T[u"outputs"]

# check positive amount
ccheck(0 < amount, "Transfer should be positive")

# check sender and receiver account
ccheck(from_account["accountId"] == from_account_new["accountId"], "Old and new account do not match")
ccheck(to_account["accountId"] == to_account_new["accountId"], "Old and new account do not match")

# check that the sender has enough fundings
ccheck(amount <= from_account["amount"], "No funds available")

# check inntegrity of the operation
ccheck(from_account["amount"] - amount == from_account_new["amount"], "Incorrect new balance")
ccheck(to_account["amount"] + amount == to_account_new["amount"], "Incorrect new balance")

# return
return {"status": "OK"}



##################################################################################
# webapp
##################################################################################
# the state of the infrastructure
app = Flask(__name__)

# -------------------------------------------------------------------------------
# /bank/transfer
# checker the correctness of a bank transfer
# -------------------------------------------------------------------------------
@app.route("/bank/transfer", methods=["GET", "POST"])
def check():
if request.method == "POST":
try:
return dumps(checker_function(loads(request.data)))
except KeyError as e:
return dumps({"status": "Error", "message": e.args})
except Exception as e:
return dumps({"status": "Error", "message": e.args})
else:
return dumps({"status": "Error", "message":"Use POST method."})


##################################################################################
# execute
##################################################################################
if __name__ == "__main__":
app.run(host="127.0.0.1", port="5001")


##################################################################################
12 changes: 9 additions & 3 deletions chainspace.iml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="gson-2.6.2" level="project" />
<orderEntry type="library" name="httpcore-4.4.6" level="project" />
<orderEntry type="library" name="httpclient-4.5.3" level="project" />
<orderEntry type="library" name="commons-logging-1.2" level="project" />
<orderEntry type="library" name="json-20140107" level="project" />
<orderEntry type="library" name="json-simple-1.1.1" level="project" />
<orderEntry type="library" name="sqlite-jdbc-3.18.0" level="project" />
</component>
</module>

</module>
Binary file added lib/commons-logging-1.2.jar
Binary file not shown.
Binary file added lib/gson-2.6.2.jar
Binary file not shown.
Binary file added lib/httpclient-4.5.3.jar
Binary file not shown.
Binary file added lib/httpcore-4.4.6.jar
Binary file not shown.
Binary file added lib/json-20140107.jar
Binary file not shown.
Binary file added lib/json-simple-1.1.1.jar
Binary file not shown.
Binary file added lib/sqlite-jdbc-3.18.0.jar
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added shard1.db
Binary file not shown.
Binary file added shard10.db
Binary file not shown.
Binary file added shard20.db
Binary file not shown.
19 changes: 19 additions & 0 deletions src/uk/ac/ucl/cs/sec/chainspace/AbortTransactionException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package uk.ac.ucl.cs.sec.chainspace;


/**
* Custom exception. Thrown when a chainspace transaction aborts.
*/
class AbortTransactionException extends Exception {

/**
* Message constructor.
*
* @param message the error message.
*/
AbortTransactionException(String message) {

super(message);

}
}
139 changes: 138 additions & 1 deletion src/uk/ac/ucl/cs/sec/chainspace/Main.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,145 @@
package uk.ac.ucl.cs.sec.chainspace;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import uk.ac.ucl.cs.sec.chainspace.examples.BankAccount;

import java.io.IOException;
import java.sql.SQLException;


/**
* Main class.
* This class run two tests ( test1() and test2() ) testing chainspace. They rely on the example client BankTransaction,
* and the python checker bank_transfer_checker.py should be running.
*/
public class Main {


/*
This list keeps all the node instances that are used for test2(). See below.
*/
static Node[] nodeList;

/**
* Main method.
*
* @param args args.
*/
public static void main(String[] args) {
// write your code here

try {

/*
This first test execute a transaction in the case where the system is composed of a single node. Therefore,
all input objects are kept by the same database.
*/
test1();

/*
This second test suppose six nodes, grouped into two shards. The transaction is submitted to all the nodes.
Each node process the transaction and ask to the other nodes if they are missing some inputs.
(We suppose that all nodes included in the same shard are sharing the same database).
*/
test2();

} catch (SQLException | ClassNotFoundException | IOException | AbortTransactionException e) {
e.printStackTrace();
}

}

/**
* Test1. all objects are in the same node.
*
* @throws SQLException SQLException.
* @throws ClassNotFoundException ClassNotFoundException.
* @throws IOException IOException.
* @throws AbortTransactionException ChainspaceException.
*/
private static void test1() throws SQLException, ClassNotFoundException, IOException, AbortTransactionException {
// init
Gson gson = new GsonBuilder().create();

// checker url
String checkerURL = "http://127.0.0.1:5001/bank/transfer";

// create Alice's account
BankAccount aliceAccount = new BankAccount("Alice", 10);
BankAccount sallyAccount = new BankAccount("Sally", 0);
String aliceAccountJson = gson.toJson(aliceAccount);
String sallyAccountJson = gson.toJson(sallyAccount);

// create transfer
Transaction transfer = aliceAccount.sendMoney(sallyAccount, 8, checkerURL);

// instantiate the node
Node node = new Node(1);

// register objects
node.registerObject(aliceAccountJson);
node.registerObject(sallyAccountJson);

// apply transaction
// Note that the transaction is first changed to JSON: nodes accept only transaction in JSON format.
node.applyTransaction(gson.toJson(transfer));

// shut down the node
node.shutdown();
}



/**
* Test2. the transaction requires an input from each node.
*
* @throws SQLException SQLException.
* @throws ClassNotFoundException ClassNotFoundException.
* @throws IOException IOException.
* @throws AbortTransactionException ChainspaceException.
*/
private static void test2() throws SQLException, ClassNotFoundException, IOException, AbortTransactionException {

// run nodes
// Nodes should not run like this: each node should be an independent webservice.
nodeList = new Node[]{
new Node(10),
new Node(10),
new Node(10),
new Node(20),
new Node(20),
new Node(20),
};

// init
Gson gson = new GsonBuilder().create();

// checker url
String checkerURL = "http://127.0.0.1:5001/bank/transfer";

// create Alice's account
BankAccount aliceAccount = new BankAccount("Alice", 10);
BankAccount sallyAccount = new BankAccount("Sally", 0);
String aliceAccountJson = gson.toJson(aliceAccount);
String sallyAccountJson = gson.toJson(sallyAccount);

// create transfer
Transaction transfer = aliceAccount.sendMoney(sallyAccount, 5, checkerURL);

// register objects
nodeList[0].registerObject(aliceAccountJson);
nodeList[3].registerObject(sallyAccountJson);

// apply transaction

for (Node node: nodeList) {
node.applyTransaction(gson.toJson(transfer));
}

// shut down the node
for (Node node: nodeList) {
node.shutdown();
}
}
}
Loading

0 comments on commit f02344f

Please sign in to comment.