From e600e4d870cfc284b66a148b45517a2526b1e93e Mon Sep 17 00:00:00 2001 From: boneyard93501 <4523011+boneyard93501@users.noreply.github.com> Date: Sun, 7 Nov 2021 18:38:20 -0600 Subject: [PATCH] update consensus --- README.md | 14 +- client-peer/aqua/demo_validation.aqua | 40 ++- client-peer/src/_aqua/demo_validation.ts | 305 +++++++++++++++++++++++ client-peer/src/index.ts | 38 ++- peer-node/data/snapshot.db | Bin 12288 -> 12288 bytes services/consensus/.repl_history | 13 - 6 files changed, 379 insertions(+), 31 deletions(-) delete mode 100644 services/consensus/.repl_history diff --git a/README.md b/README.md index 490b44e..92965f4 100644 --- a/README.md +++ b/README.md @@ -137,25 +137,23 @@ signed eip validation result: { ``` We should have one record in the node db and have 1 record(s). -We know from the EIP document that the snapshot is 9278489, which i used as a unique key in the sqlite db and we can call individual recirds by snapshot id: +We know from the EIP document that the snapshot is 9278489, which i used as a unique key in the sqlite db and we can call individual records by the signature: ``` -result for call with 9278489: { - stderr: '', +result for call with 0xc0a90a0bf43c0b774570608bf0279143b366b7880798112b678b416a7500576b41e19f7b4eb457d58de29be3a201f700fafab1f02179da0faae653b7e8ecf82b1c: stderr: '', stdout: [ { - signature: 0xdd91572e2e721a59ca62abd4ec07c55b9496bf10969112e6c1dbb9936394bd5a602b2f697b1bb0910edb72a726bc1f05a0f13d9cbf5bc715f87211f40c75348e1c, + signature: '0xc0a90a0bf43c0b774570608bf0279143b366b7880798112b678b416a7500576b41e19f7b4eb457d58de29be3a201f700fafab1f02179da0faae653b7e8ecf82b1c', event_address: '0xeF8305E140ac520225DAf050e2f71d5fBcC543e7', - event_signature: '0xc0a90a0bf43c0b774570608bf0279143b366b7880798112b678b416a7500576b41e19f7b4eb457d58de29be3a201f700fafab1f02179da0faae653b7e8ecf82b1c', eip712_doc: '{"domain":{"name":"snapshot","version":"0.1.4"},"types":{"Proposal":[{"name":"from","type":"address"},{"name":"space","type":"string"},{"name":"timestamp","type":"uint64"},{"name":"type","type":"string"},{"name":"title","type":"string"},{"name":"body","type":"string"},{"name":"choices","type":"string[]"},{"name":"start","type":"uint64"},{"name":"end","type":"uint64"},{"name":"snapshot","type":"uint64"},{"name":"network","type":"string"},{"name":"strategies","type":"string"},{"name":"plugins","type":"string"},{"name":"metadata","type":"string"}]},"message":{"space":"fabien.eth","type":"single-choice","title":"This is a long title this is a long title this is a long title this is a long title this is a long title this is a long","body":"This is a long title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title title this is a long title this is a long title.","choices":["Approve","Reject"],"start":1630472400,"end":1640926800,"snapshot":9278489,"network":"4","strategies":"[{\\"name\\":\\"ticket\\",\\"params\\":{\\"value\\":100,\\"symbol\\":\\"$\\"}}]","plugins":"{}","metadata":"{}","from":"0xeF8305E140ac520225DAf050e2f71d5fBcC543e7","timestamp":1631432106}}', peer_id: '0x14791697260E4c9A71f18484C9f997B308e59325', - timestamp: 1635119977, + timestamp: 1636325528, eip_validation: 1, ts_validation: 0, - signed_response: '0x2571d1f9d003bd5b24f26abd21e0ebafc57aa61f0c6e85f85a9e298ff577e03445cbf182991cf263e7a3ef505276eaa9d160b780355379bed55c912dfa23623f1b' + signed_response: '0x4bb6846fd1adf2c2bfcedeae915007ff3e5a16675ae2f130749e5dc5bb17f99b095328460b12fddf2c743e06b28a9e40a970ac33f572da7bba3c4bf9b94f7a451b' } ] } -result for call with bad 92784890: { stderr: '', stdout: [ null ] } +result for call with bad 0xc0a90a0bf43c0b774570608bf0279143b366b7880798112b678b416a7500576b41e19f7b4eb457d58de29be3a201f700fafab1f02179da0faae653b7e8ecf82b1cX: { stderr: '', stdout: [ null ] } ``` ## Integration With Additional Store Solutions diff --git a/client-peer/aqua/demo_validation.aqua b/client-peer/aqua/demo_validation.aqua index c847715..abc64c0 100644 --- a/client-peer/aqua/demo_validation.aqua +++ b/client-peer/aqua/demo_validation.aqua @@ -67,23 +67,45 @@ func delete_records(password: string, node: string, relay:string) -> DBResult: -- Example to collect many node validations and run them through a simple frequency count -- algorithm data EIPLocation: - node: string - relay: string + node_id: string + relay_id: string + +data Consensus: + n: u64 + threshold: f64 + valid: u64 + invalid: u64 + consensus: bool + +data CResult: + stderr: string + stdout: []Consensus service ConsensusService("ConsensusService"): - consensus([]bool) -> bool + consensus(validations: []bool, threshold: f64) -> CResult -func eip_consensus((signature: string, node_locations:[]EIPLocation, service_node: string, consensus_service: string) -> bool: + + +func eip_consensus_halfway(signature: string, locations:[]EIPLocation, service_node: string, consensus_service: string, threshold: f64) -> []bool: result: *bool - for loc in node_locations par: - on node via relay: + for loc <- locations: + on loc.node_id via loc.relay_id: res <- DataProvider.get_record(signature) - result <- res.ts_validation - + result <<- res.stdout!0.ts_validation + <- result + +func eip_consensus(signature: string, locations:[]EIPLocation, service_node: string, consensus_service: string, threshold: f64) -> CResult: + result: *bool + + for loc <- locations par: + on loc.node_id via loc.relay_id: + res <- DataProvider.get_record(signature) + result <<- res.stdout!0.ts_validation + on service_node: ConsensusService consensus_service - consensus <- ConsensusService.consensus(result) + consensus <- ConsensusService.consensus(result, threshold) <- consensus diff --git a/client-peer/src/_aqua/demo_validation.ts b/client-peer/src/_aqua/demo_validation.ts index b3a9604..c9f044b 100644 --- a/client-peer/src/_aqua/demo_validation.ts +++ b/client-peer/src/_aqua/demo_validation.ts @@ -146,6 +146,48 @@ export function registerDataProvider(...args: any) { ); } + + +export interface ConsensusServiceDef { + consensus: (validations: boolean[], threshold: number, callParams: CallParams<'validations' | 'threshold'>) => { stderr: string; stdout: { consensus: boolean; invalid: number; n: number; threshold: number; valid: number; }[]; } | Promise<{ stderr: string; stdout: { consensus: boolean; invalid: number; n: number; threshold: number; valid: number; }[]; }>; +} +export function registerConsensusService(service: ConsensusServiceDef): void; +export function registerConsensusService(serviceId: string, service: ConsensusServiceDef): void; +export function registerConsensusService(peer: FluencePeer, service: ConsensusServiceDef): void; +export function registerConsensusService(peer: FluencePeer, serviceId: string, service: ConsensusServiceDef): void; + + +export function registerConsensusService(...args: any) { + registerService( + args, + { + "defaultServiceId" : "ConsensusService", + "functions" : [ + { + "functionName" : "consensus", + "argDefs" : [ + { + "name" : "validations", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "threshold", + "argType" : { + "tag" : "primitive" + } + } + ], + "returnType" : { + "tag" : "primitive" + } + } + ] +} + ); +} + // Functions export type Get_recordResult = { stderr: string; stdout: { eip712_doc: string; eip_validation: boolean; event_address: string; peer_id: string; signature: string; signed_response: string; timestamp: number; ts_validation: boolean; }[]; } @@ -338,6 +380,127 @@ export function delete_records(...args: any) { } + +export function eip_consensus_halfway(signature: string, locations: { node_id: string; relay_id: string; }[], service_node: string, consensus_service: string, threshold: number, config?: {ttl?: number}): Promise; +export function eip_consensus_halfway(peer: FluencePeer, signature: string, locations: { node_id: string; relay_id: string; }[], service_node: string, consensus_service: string, threshold: number, config?: {ttl?: number}): Promise; +export function eip_consensus_halfway(...args: any) { + + let script = ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "signature") [] signature) + ) + (call %init_peer_id% ("getDataSrv" "locations") [] locations) + ) + (call %init_peer_id% ("getDataSrv" "service_node") [] service_node) + ) + (call %init_peer_id% ("getDataSrv" "consensus_service") [] consensus_service) + ) + (call %init_peer_id% ("getDataSrv" "threshold") [] threshold) + ) + (fold locations loc + (seq + (seq + (seq + (seq + (seq + (call -relay- ("op" "noop") []) + (call loc.$.relay_id! ("op" "noop") []) + ) + (xor + (seq + (call loc.$.node_id! ("DataProvider" "get_record") [signature] res) + (ap res.$.stdout.[0].ts_validation! $result) + ) + (seq + (seq + (seq + (call loc.$.relay_id! ("op" "noop") []) + (call -relay- ("op" "noop") []) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + (call -relay- ("op" "noop") []) + ) + ) + ) + (call loc.$.relay_id! ("op" "noop") []) + ) + (call -relay- ("op" "noop") []) + ) + (next loc) + ) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [$result.$.[0]!]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + ) + ` + return callFunction( + args, + { + "functionName" : "eip_consensus_halfway", + "returnType" : { + "tag" : "primitive" + }, + "argDefs" : [ + { + "name" : "signature", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "locations", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "service_node", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "consensus_service", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "threshold", + "argType" : { + "tag" : "primitive" + } + } + ], + "names" : { + "relay" : "-relay-", + "getDataSrv" : "getDataSrv", + "callbackSrv" : "callbackSrv", + "responseSrv" : "callbackSrv", + "responseFnName" : "response", + "errorHandlingSrv" : "errorHandlingSrv", + "errorFnName" : "error" + } +}, + script + ) +} + + export type ValidateResult = { stderr: string; stdout: { signature: string; validation: { eip_validation: boolean; peer_id: string; timestamp: number; ts_validation: boolean; }; }; } export function validate(eip712_url: string, node: string, relay: string, config?: {ttl?: number}): Promise; export function validate(peer: FluencePeer, eip712_url: string, node: string, relay: string, config?: {ttl?: number}): Promise; @@ -603,3 +766,145 @@ export function get_records(...args: any) { script ) } + + +export type Eip_consensusResult = { stderr: string; stdout: { consensus: boolean; invalid: number; n: number; threshold: number; valid: number; }[]; } +export function eip_consensus(signature: string, locations: { node_id: string; relay_id: string; }[], service_node: string, consensus_service: string, threshold: number, config?: {ttl?: number}): Promise; +export function eip_consensus(peer: FluencePeer, signature: string, locations: { node_id: string; relay_id: string; }[], service_node: string, consensus_service: string, threshold: number, config?: {ttl?: number}): Promise; +export function eip_consensus(...args: any) { + + let script = ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "signature") [] signature) + ) + (call %init_peer_id% ("getDataSrv" "locations") [] locations) + ) + (call %init_peer_id% ("getDataSrv" "service_node") [] service_node) + ) + (call %init_peer_id% ("getDataSrv" "consensus_service") [] consensus_service) + ) + (call %init_peer_id% ("getDataSrv" "threshold") [] threshold) + ) + (fold locations loc + (par + (seq + (seq + (seq + (seq + (call -relay- ("op" "noop") []) + (call loc.$.relay_id! ("op" "noop") []) + ) + (xor + (seq + (call loc.$.node_id! ("DataProvider" "get_record") [signature] res) + (ap res.$.stdout.[0].ts_validation! $result) + ) + (seq + (seq + (seq + (seq + (call loc.$.relay_id! ("op" "noop") []) + (call -relay- ("op" "noop") []) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + (call -relay- ("op" "noop") []) + ) + (call loc.$.relay_id! ("op" "noop") []) + ) + ) + ) + (call loc.$.relay_id! ("op" "noop") []) + ) + (call service_node ("op" "noop") []) + ) + (next loc) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (seq + (call -relay- ("op" "noop") []) + (call service_node (consensus_service "consensus") [$result threshold] consensus) + ) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [consensus]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 4]) + ) + ` + return callFunction( + args, + { + "functionName" : "eip_consensus", + "returnType" : { + "tag" : "primitive" + }, + "argDefs" : [ + { + "name" : "signature", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "locations", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "service_node", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "consensus_service", + "argType" : { + "tag" : "primitive" + } + }, + { + "name" : "threshold", + "argType" : { + "tag" : "primitive" + } + } + ], + "names" : { + "relay" : "-relay-", + "getDataSrv" : "getDataSrv", + "callbackSrv" : "callbackSrv", + "responseSrv" : "callbackSrv", + "responseFnName" : "response", + "errorHandlingSrv" : "errorHandlingSrv", + "errorFnName" : "error" + } +}, + script + ) +} diff --git a/client-peer/src/index.ts b/client-peer/src/index.ts index a50b485..e87c1de 100644 --- a/client-peer/src/index.ts +++ b/client-peer/src/index.ts @@ -17,6 +17,7 @@ import { Fluence, setLogLevel, FluencePeer } from "@fluencelabs/fluence"; import { krasnodar, Node } from "@fluencelabs/fluence-network-environment"; import { validate, get_record, get_records, get_record_count, delete_records } from "./_aqua/demo_validation"; +import { eip_consensus, eip_consensus_halfway } from "./_aqua/demo_validation"; const NODE_DB_PWD = "bad really bad"; const PWD_HASH = "bad really bad"; @@ -24,7 +25,7 @@ const EIP712_URL = "https://ipfs.fleek.co/ipfs/QmWGzSQFm57ohEq2ATw4UNHWmYU2HkMjt interface NodeTuple { node_id: string; - relay_id: string + relay_id: string; } // PoC node parameters @@ -35,6 +36,29 @@ let poc_topologies: Array = [ }, ]; +interface ServiceTuple { + node_id: string; + service_id: string; +} + +let service_topology: ServiceTuple = { + "node_id": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf", + "service_id": "932e002f-12b9-48cd-9616-7f15bb1e4ef3" +} + + +interface Consensus { + n: number; + threshold: number; + valid: number; + invalid: number; + consensus: boolean; +} + +interface CResult { + stderr: string; + stdout: Array; // always length 0 or 1 +} async function main() { @@ -78,6 +102,18 @@ async function main() { console.log("result for call with 0xc0a90a0bf43c0b774570608bf0279143b366b7880798112b678b416a7500576b41e19f7b4eb457d58de29be3a201f700fafab1f02179da0faae653b7e8ecf82b1c: ", good_record); console.log("result for call with bad 0xc0a90a0bf43c0b774570608bf0279143b366b7880798112b678b416a7500576b41e19f7b4eb457d58de29be3a201f700fafab1f02179da0faae653b7e8ecf82b1cX: ", bad_record); + + let threshold: number = 0.666; + let sig = "0xc0a90a0bf43c0b774570608bf0279143b366b7880798112b678b416a7500576b41e19f7b4eb457d58de29be3a201f700fafab1f02179da0faae653b7e8ecf82b1c"; + console.log("\n\nsimple consensus calculation for one (1) node result with threshold ", threshold); + + let half_way = await eip_consensus_halfway(sig, poc_topologies, service_topology.node_id, service_topology.service_id, threshold); + console.log("just for testing half_way: ", half_way); + + let consensus = await eip_consensus(sig, poc_topologies, service_topology.node_id, service_topology.service_id, threshold); + console.log("consensus: ", consensus); + + return; } diff --git a/peer-node/data/snapshot.db b/peer-node/data/snapshot.db index 80be5cc307fdaed55fc8bf3d7a5f61aeb1609b79..3db890211ad70d26e8d72b40870ff5f275367575 100644 GIT binary patch delta 157 zcmWN}yA1*{3;<9a1vM=K=~l24J5FjAx%d+?0v%UU!YGK@Xc1RG>8;DUJWmt7&X!5LlDBN)uE{wkjE&1Ov4R1 hycnn})of%1xxw~u^Wu~mgz4bTd7n^F?DLy i\nLoaded modules interface:\ndata CResult:\n stderr: string\n stdout: []Consensus\ndata Consensus:\n n: u64\n threshold: f64\n valid: u64\n invalid: u64\n consensus: bool\n\nconsensus:\n fn consensus(payload: []bool, threshold: f64) -> CResult\n\n2> call consensus consensus [[true,true, true, true,false,false], 0.666]\nresult: Object({"stderr": String(""), "stdout": Array([Object({"consensus": Bool(true), "invalid": Number(2), "n": Number(6), "threshold": Number(0.666), "valid": Number(4)})])})\n elapsed time: 96.859µs\n\n3> call consensus consensus [[true,true, true, false,false,false], 0.666]\nresult: Object({"stderr": String(""), "stdout": Array([Object({"consensus": Bool(false), "invalid": Number(3), "n": Number(6), "threshold": Number(0.666), "valid": Number(3)})])})\n elapsed time: 52.831µs\n\n4> -1> i\nLoaded modules interface:\ndata CResult:\n stderr: string\n stdout: []Consensus\ndata Consensus:\n n: u64\n threshold: f64\n valid: u64\n invalid: u64\n consensus: bool\n\nconsensus:\n fn consensus(payload: []bool, threshold: f64) -> CResult\n\n2> call consensus consensus [[true,true, true, true,false,false], 0.666]\nresult: Object({"stderr": String(""), "stdout": Array([Object({"consensus": Bool(true), "invalid": Number(2), "n": Number(6), "threshold": Number(0.666), "valid": Number(4)})])})\n elapsed time: 96.859µs\n\n3> call consensus consensus [[true,true, true, false,false,false], 0.666]\nresult: Object({"stderr": String(""), "stdout": Array([Object({"consensus": Bool(false), "invalid": Number(3), "n": Number(6), "threshold": Number(0.666), "valid": Number(3)})])})\n elapsed time: 52.831µs\n\n4>call consensus consensus [[true,true, false, false,false,false], 0.666] -1> i\nLoaded modules interface:\ndata CResult:\n stderr: string\n stdout: []Consensus\ndata Consensus:\n n: u64\n threshold: f64\n valid: u64\n invalid: u64\n consensus: bool\n\nconsensus:\n fn consensus(payload: []bool, threshold: f64) -> CResult\n\n2> call consensus consensus [[true,true, true, true,false,false], 0.666]\nresult: Object({"stderr": String(""), "stdout": Array([Object({"consensus": Bool(true), "invalid": Number(2), "n": Number(6), "threshold": Number(0.666), "valid": Number(4)})])})\n elapsed time: 96.859µs\n\n3> call consensus consensus [[true,true, true, false,false,false], 0.666]\nresult: Object({"stderr": String(""), "stdout": Array([Object({"consensus": Bool(false), "invalid": Number(3), "n": Number(6), "threshold": Number(0.666), "valid": Number(3)})])})\nlapsed time: 52.831µs\n\n4>call consensus consensus [[true,true, false, false,false,false], 0.666] -i -call consensus consensus [[true,true, false, false,false,false], 0.666]