Skip to content

Commit

Permalink
Revert "Revert "POC implementation of Payments""
Browse files Browse the repository at this point in the history
  • Loading branch information
nkostoulas authored Nov 22, 2019
1 parent cbb6b82 commit 538b275
Show file tree
Hide file tree
Showing 34 changed files with 1,725 additions and 876 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@

# 0.3.x

1. Fix issue with coordinator not storing empty responses
2. Report script improvements
3. Height checks in service not clientchain
4. Challenge asset key import
5. Docker secrets
6. Docker secrets
7. Bitcoin library updates
8. Docker secrets
9. Enhancements

# 0.3.0

* RPC API

# 0.2.0

* Finished core interfaces and testing
Expand Down
321 changes: 131 additions & 190 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "coordinator"
version = "0.1.0"
version = "0.3.9"
authors = ["nkostoulas <[email protected]>"]
description = "Guardnode Coordinator implementation for the Commerceblock Covalence system"
homepage = "https://github.com/commerceblock"
Expand All @@ -19,6 +19,4 @@ mongodb = "0.3.11"
jsonrpc-http-server = "11.0"
rust-ocean = { git = "https://github.com/commerceblock/rust-ocean"}
ocean-rpc = { git = "https://github.com/commerceblock/rust-ocean-rpc"}
bitcoin = { version = "0.17", features = [ "serde-decimal" ] }
bitcoin_hashes = "0.3"
secp256k1 = "0.12.2"
bitcoin = { version = "0.20", features = [ "use-serde" ] }
15 changes: 8 additions & 7 deletions config/default.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Log level option used to set RUST_LOG for the rust env logger
log_level = "coordinator,demo"
# log_level = "coordinator,demo"

# Duration that we wait for challenge responses from guardnodes, in seconds
challenge_duration = 60
# challenge_duration = 60

# Frequency of creating new challenges, in number of blocks
challenge_frequency = 2
# challenge_frequency = 2

# Duration that we attempt to verify a challenge transaction before skipping, in seconds
verify_duration = 150
# Block find time of service chain, in seconds
# block_time = 60

# Host address that the listener binds to and receives guardnode requests
listener_host = "127.0.0.1:9999"
Expand All @@ -28,11 +28,12 @@ host = "127.0.0.1:5555"
user = "user1"
pass = "password1"
genesis_hash = "ff8950160a77988cdc485913568d06c2d69a8c952ef0f179b4b097e3de63d7cc"
block_time = 60
asset = "CHALLENGE"
asset_key = "cScSHCQp9AEwzZoucRpX9bMRkLCJ4LoQWBNFTZuD6tPX9qwNMWfQ"
chain = "ocean_test"
payment_asset = "CBT"

[storage]
host = "localhost:27017"
name = "coordinator"
user = "user"
pass = "pass"
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ services:
CO_CLIENTCHAIN_PASS: password1
CO_CLIENTCHAIN_GENESIS_HASH: d1fbd07bd9a7a80a85445b8e28246f0b644c01ac7412e81ce3ffc0815386ad77
CO_CLIENTCHAIN_ASSET_KEY: cScSHCQp9AEwzZoucRpX9bMRkLCJ4LoQWBNFTZuD6tPX9qwNMWfQ
CO_CLIENTCHAIN_CHAIN: ocean_test
CO_CLIENTCHAIN_PAYMENT_ASSET: CBT

# cb service chain node connectivity
CO_SERVICE_HOST: service_chain:5555
Expand Down
24 changes: 14 additions & 10 deletions examples/demo.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
//! Simple demo of coordinator with mock guard node
//!
//! Demo Coordinator connects to demo client chain (can be built by running
//! ./scripts/demo.sh) and sends challenges to mock guardnodes that made bids.
//! When guardnode responses are received by coordinator they are verified and
//! can be stored ready for fee payments to be made.
#[macro_use]
extern crate log;
extern crate bitcoin;
extern crate bitcoin_hashes;
extern crate coordinator;
extern crate env_logger;
extern crate hyper;
extern crate ocean_rpc;
extern crate secp256k1;

use std::sync::Arc;
use std::{env, thread, time};

use bitcoin::consensus::encode::serialize;
use bitcoin_hashes::{hex::FromHex, hex::ToHex, sha256d};
use bitcoin::hashes::{hex::FromHex, hex::ToHex, sha256d};
use bitcoin::secp256k1::{Message, Secp256k1, SecretKey};
use hyper::{
rt::{self, Future, Stream},
Body, Client, Method, Request,
};
use ocean_rpc::RpcApi;
use secp256k1::{Message, Secp256k1, SecretKey};

use coordinator::clientchain::get_first_unspent;
use coordinator::coordinator as coordinator_main;
use coordinator::ocean::OceanClient;
use coordinator::interfaces::clientchain::get_first_unspent;
use coordinator::util::ocean::OceanClient;

/// Demo coordinator with listener and challenge service running
/// mock implementation for service chain interface and ocean
Expand All @@ -33,9 +36,11 @@ use coordinator::ocean::OceanClient;
fn main() {
let mut config = coordinator::config::Config::new().unwrap();
config.challenge_duration = 5;
config.verify_duration = 30;
config.challenge_frequency = 2;
config.block_time = 10;
config.clientchain.block_time = 10;

env::set_var("RUST_LOG", &config.log_level);
env::set_var("RUST_LOG", "coordinator,demo");
env::set_var("RUST_BACKTRACE", "1");
env_logger::init();

Expand All @@ -51,7 +56,7 @@ fn main() {
// auto client chain block generation
let client_rpc_clone = client_rpc.clone();
thread::spawn(move || loop {
thread::sleep(time::Duration::from_secs(5));
thread::sleep(time::Duration::from_secs(10));
if let Err(e) = client_rpc_clone.clone().client.generate(1) {
error!("{}", e);
}
Expand All @@ -68,7 +73,6 @@ fn main() {
for bid in client_rpc.get_request_bids(&request_txid).unwrap().unwrap().bids {
if bid.fee_pub_key.to_string() == guardnode_pubkey {
guardnode_txid = bid.txid;
println!("guardnode bid txid: {}", guardnode_txid);
break;
}
}
Expand Down
8 changes: 3 additions & 5 deletions examples/hyperclient.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
//! Mock Example of client sending a POST request to server
extern crate bitcoin;
extern crate bitcoin_hashes;
extern crate hyper;
extern crate secp256k1;

use bitcoin::consensus::encode::serialize;
use bitcoin_hashes::hex::{FromHex, ToHex};
use bitcoin_hashes::sha256d;
use bitcoin::hashes::hex::{FromHex, ToHex};
use bitcoin::hashes::sha256d;
use bitcoin::secp256k1::{Message, Secp256k1, SecretKey};
use hyper::{
header::HeaderValue,
rt::{self, Future, Stream},
Body, Client, Method, Request,
};
use secp256k1::{Message, Secp256k1, SecretKey};

fn main() {
let client = Client::new();
Expand Down
4 changes: 2 additions & 2 deletions examples/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
extern crate ocean_rpc;
extern crate rust_ocean;

use ocean_rpc::{Client, Error, RpcApi};
use ocean_rpc::{Auth, Client, Error, RpcApi};

fn main_result() -> Result<(), Error> {
let mut args = std::env::args();
Expand All @@ -14,7 +14,7 @@ fn main_result() -> Result<(), Error> {
let user = args.next();
let pass = args.next();

let rpc = Client::new(url, user, pass);
let rpc = Client::new(url, Auth::UserPass(user.unwrap(), pass.unwrap())).unwrap();

let blockchain_info = rpc.get_blockchain_info()?;
println!("info\n{:?}", blockchain_info);
Expand Down
9 changes: 9 additions & 0 deletions scripts/create_request.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# Script builds, signs and sends a request transaction on service chain whose
# connectivity information is specified in $RPC_USER, RPC_PASS, RPC_CONNECT,
# and RPC_PORT env variables from the local ocean wallet.
#
# Several checks are made for validity of given arguments. If all is well then an
# unspent permission asset output is found (or provided in argument 9 and 10) and
# used as input to a raw request tx. The request is broadcast and its spending script
# address imported to the wallet to allow for automatic renewal of the request.

#!/bin/bash
shopt -s expand_aliases
alias ocl="$HOME/jsonrpc-cli/jsonrpc-cli --user=$RPC_USER --pass=$RPC_PASS --format=jsonpretty --resultonly=on --highlight=off http://$RPC_CONNECT:$RPC_PORT/"
Expand Down
5 changes: 5 additions & 0 deletions scripts/demo.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Script spins up new chain with datadir=~/co-client-dir/ and creates a new
# demo request transaction along with 2 bids. This can be used to initialise
# exmples/demo.rs to perform coordinator functionality on a mock client and service
# chain.

#!/bin/bash
shopt -s expand_aliases

Expand Down
37 changes: 19 additions & 18 deletions scripts/report.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Script to generate report of responses from guardnodes using
# coordinator RPC API interface.
#
# First connection to a local Ocean node is made, the request data for a
# txid is found via getrequest RPC and fee size is calculated.
# Then getrequestresponse RPC is called to get challenge responses which can be
# used to determine rewards for guardnodes.

#!/usr/bin/env python3
import requests
import json
Expand Down Expand Up @@ -74,9 +82,9 @@ def calculate_fees(rpc, start_height, end_height):
return fee

addr_prefix = 235
txid = "78f954d07de5badbc1526a60fe0ea639216f17f490a3bf41e48840453eca243f"
url = 'https://userApi:passwordApi@coordinator-api.testnet.commerceblock.com:10006'
rpc = connect("ocean", "oceanpass", "localhost", "7043")
txid = "6e993034df3203c0867c98f420f85b5ffecd7cb8580e2b6f2d33764e1cbfb074"
url = 'http://userApi:passwordApi@localhost:3333'
rpc = connect("user1", "password1", "localhost", "5555")

payload = '{{"jsonrpc": "2.0", "method": "getrequest", "params": {{"txid": "{}"}}, "id": 1}}'.format(txid)
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
Expand All @@ -90,11 +98,8 @@ def calculate_fees(rpc, start_height, end_height):
print("")

print("Calculating total fees...")
# For requests that are serving the service chain the fee start/end heights
# can be picked up from the request information. For requests in client chains
# these heights need to be found manually and inserted below to calculate fees
fee_start_height = request['start_blockheight']
fee_end_height = request['end_blockheight']
fee_start_height = request['start_blockheight_clientchain']
fee_end_height = request['end_blockheight_clientchain']
fee = calculate_fees(rpc, fee_start_height, fee_end_height)
fee_percentage = request['fee_percentage']
fee_out = fee*fee_percentage/100
Expand All @@ -112,21 +117,17 @@ def calculate_fees(rpc, start_height, end_height):
fee_per_guard = float(fee_out/len(bids))
print("")

payload = '{{"jsonrpc": "2.0", "method": "getrequestresponses", "params": {{"txid": "{}"}}, "id": 1}}'.format(txid)
payload = '{{"jsonrpc": "2.0", "method": "getrequestresponse", "params": {{"txid": "{}"}}, "id": 1}}'.format(txid)
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.post(url, data=payload, headers=headers)

result = json.loads(json.loads(r.content)['result'])
challenge_resps = result["responses"]
num_of_challenges = len(challenge_resps)
challenge_resps = result["response"]
num_of_challenges = challenge_resps["num_challenges"]
print("Number of challenges: {}".format(num_of_challenges))
resps = {}
for challenge_resp in challenge_resps:
for bid_resp in challenge_resp:
if bid_resp in resps:
resps[bid_resp] += (1/num_of_challenges)
else:
resps[bid_resp] = (1/num_of_challenges)
for (bid, resp_num) in challenge_resps["bid_responses"].items():
resps[bid] = resp_num / num_of_challenges

print("Results")
for bid, key in bids.items():
Expand All @@ -135,4 +136,4 @@ def calculate_fees(rpc, start_height, end_height):
performance = resps[bid]
print("Bid {0}\npubkey: {1}\naddress: {2}\nperformance: {3:.2f}%\nreward: {4}\n".\
format(bid, key, key_to_p2pkh(key, addr_prefix), 100*performance, fee_per_guard*performance))
print("End")
print("End")
Loading

0 comments on commit 538b275

Please sign in to comment.