update readme, cleanup comments

This commit is contained in:
boneyard93501 2021-10-24 19:10:23 -05:00
parent 2c59a94479
commit 4f163db19b
7 changed files with 108 additions and 83 deletions

View File

@ -30,7 +30,7 @@ The implemented peer exposes select interfaces to be used with Aqua and operates
The PoC implementation does not provide integration with external Snapshot distributed persistence but allows for easy extension to incorporate exogenous storage solutions. The validation process, including not implemented checks, can be found in [eip_validation](./src/eip_processor.ts) and the local persistence in [local sqlite](./src/local_db.ts). The PoC implementation does not provide integration with external Snapshot distributed persistence but allows for easy extension to incorporate exogenous storage solutions. The validation process, including not implemented checks, can be found in [eip_validation](./src/eip_processor.ts) and the local persistence in [local sqlite](./src/local_db.ts).
In order to access the services with Aqua, please see [implementation](./aqua/snapshot.aqua), which can be fired from a Typescript client, another peer or the `fldist` command line tool. In order to access the services with Aqua, please see the [implementation](./aqua/snapshot.aqua), which can be fired from a Typescript client, another peer or the [`fldist`](https://github.com/fluencelabs/fldist) command line tool or it's successor cli [Aqua](https://github.com/fluencelabs/aqua).
In addition, Aqua can be used to query a Peer's local database for already processed validations. This allows new peers, for example, to build up a local history of previously validated events, if so desired. Please note that a consensus algorithm should be implemented and used to manage the sync process. The query process is outlined in Figure 2 below and the Aqua queries are located in [snapshot aqua](./aqua/snapshot.aqua). In addition, Aqua can be used to query a Peer's local database for already processed validations. This allows new peers, for example, to build up a local history of previously validated events, if so desired. Please note that a consensus algorithm should be implemented and used to manage the sync process. The query process is outlined in Figure 2 below and the Aqua queries are located in [snapshot aqua](./aqua/snapshot.aqua).
@ -73,23 +73,88 @@ TODO:
## Running A Peer ## Running A Peer
Install the Node dependencies and start the peer in the `` directory: In your terminal in the `peer-node` directory, install the dependencies, compile the Aqua script and start the peer:
```bash ```bash
npm i npm i
npm run compile-aqua
npm start npm start
``` ```
Or run with And the ensuing terminal output should look like this:
```bash ```bash
nohup node start & > snapshot-node-poc@0.1.0 start
> node -r ts-node/register src/index.ts
Snapshot service node running with ...
wallet from sk: 0x14791697260E4c9A71f18484C9f997B308e59325
wallet pk: 0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e
PeerId: 12D3KooWFCY8xqebtZqNeiA5took71bUNAedzCCDuCuM1QTdTbWT
Relay id: 12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e
crtl-c to exit
``` ```
for a long-running daemon. ## Running A Client
With the node up and running, we can access the validation and query capabilities with Aqua initiated from any other (client) peer including a browser. We can currently call the validation process from [Aqua](./aqua/snapshot.aqua) with two methods: `validate` and `validate_from_url` with the former accepting a json string and the later the url to a json body. With the node up and running, open a new terminal window and in the `client-peer` directory install the dependencies and start the client:
Using the command line utility [`fldist`]("https://doc.fluence.dev/docs/knowledge_tools"), for example, we can run: ```bash
npm i
npm run compile-aqua
npm start
```
The client executes a validation and a few node-local database calls specified in the `aqua\demo_validation.aqua` file. Note that the client could be a browser, see the [Quickstart](https://doc.fluence.dev/docs/quick-start) documentation for examples. The expected output for the demo should looks like this:
TBD ```bash
> snapshot-demo-client@0.1.0 start
> node -r ts-node/register src/index.ts
Welcome to Snapshot PoC demo.
Created Fluence client with
peer id: 12D3KooWNRrP7cZ5VcYrCeYBc9RuWz5ijcayD6iGkJKdayzhtQaG
relay id 12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA
Roundtrip Validation demo.
Let's check the node db and clear all records if need be:
deleting 1 records
Lets validate proposal https://ipfs.fleek.co/ipfs/QmWGzSQFm57ohEq2ATw4UNHWmYU2HkMjtedcNLodYywpmS, which is old and should fail.
signed eip validation result: {
stderr: '',
stdout: {
signature: '0x2571d1f9d003bd5b24f26abd21e0ebafc57aa61f0c6e85f85a9e298ff577e03445cbf182991cf263e7a3ef505276eaa9d160b780355379bed55c912dfa23623f1b',
validation: {
peer_id: '0x14791697260E4c9A71f18484C9f997B308e59325',
timestamp: 1635119977,
eip_validation: true,
ts_validation: false
}
}
}
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 sued as a unique key in the sqlite db.
and we can call individual recirds by snapshot:
result for call with 9278489: {
stderr: '',
stdout: [
{
snapshot_id: 9278489,
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,
eip_validation: 1,
ts_validation: 0,
signed_response: '0x2571d1f9d003bd5b24f26abd21e0ebafc57aa61f0c6e85f85a9e298ff577e03445cbf182991cf263e7a3ef505276eaa9d160b780355379bed55c912dfa23623f1b'
}
]
}
result for call with bad 92784890: { stderr: '', stdout: [ null ] }
```
## Integration With Additional Store Solutions
Adding (distributed) store solutions for query and persistance on both node and client is straight forward. For Aqua-based IPFS and Ceramic integration examples see [aqua-ipfs](https://github.com/fluencelabs/examples/tree/main/aqua-examples/aqua-ipfs-integration) and [aqua-ipfs lib](https://doc.fluence.dev/aqua-book/libraries/aqua-ipfs) and [ceramic-ipfs](https://github.com/fluencelabs/examples/tree/main/aqua-examples/aqua-ceramic-integration), respectively.

View File

@ -1,3 +1,18 @@
data Response:
peer_id: string
timestamp: u64
eip_validation: bool
ts_validation: bool
data EipResponse:
signature: string
validation: Response
data ValidationResult:
stderr: string
stdout: EipResponse
data DBRecord: data DBRecord:
snapshot_id: u64 snapshot_id: u64
event_address: string event_address: string
@ -14,8 +29,8 @@ data DBResult:
stdout: []DBRecord stdout: []DBRecord
service EIPValidator("EIPValidator"): service EIPValidator("EIPValidator"):
eip712_validation_string(eip_str: string, peer_id: string) -> string eip712_validation_string(eip_str: string, peer_id: string) -> ValidationResult
eip712_validation_url(eip_str: string, peer_id: string) -> string eip712_validation_url(eip_str: string, peer_id: string) -> ValidationResult
service DataProvider("DataProvider"): service DataProvider("DataProvider"):
get_records() -> DBResult get_records() -> DBResult
@ -24,7 +39,7 @@ service DataProvider("DataProvider"):
delete_records(password: string) -> DBResult delete_records(password: string) -> DBResult
func validate(eip712_url: string, node: string, relay:string) -> string: func validate(eip712_url: string, node: string, relay:string) -> ValidationResult:
on node via relay: on node via relay:
res <- EIPValidator.eip712_validation_url(eip712_url, node) res <- EIPValidator.eip712_validation_url(eip712_url, node)
<- res <- res

View File

@ -17,8 +17,8 @@ import {
// Services // Services
export interface EIPValidatorDef { export interface EIPValidatorDef {
eip712_validation_string: (eip_str: string, peer_id: string, callParams: CallParams<'eip_str' | 'peer_id'>) => string | Promise<string>; eip712_validation_string: (eip_str: string, peer_id: string, callParams: CallParams<'eip_str' | 'peer_id'>) => { stderr: string; stdout: { signature: string; validation: { eip_validation: boolean; peer_id: string; timestamp: number; ts_validation: boolean; }; }; } | Promise<{ stderr: string; stdout: { signature: string; validation: { eip_validation: boolean; peer_id: string; timestamp: number; ts_validation: boolean; }; }; }>;
eip712_validation_url: (eip_str: string, peer_id: string, callParams: CallParams<'eip_str' | 'peer_id'>) => string | Promise<string>; eip712_validation_url: (eip_str: string, peer_id: string, callParams: CallParams<'eip_str' | 'peer_id'>) => { stderr: string; stdout: { signature: string; validation: { eip_validation: boolean; peer_id: string; timestamp: number; ts_validation: boolean; }; }; } | Promise<{ stderr: string; stdout: { signature: string; validation: { eip_validation: boolean; peer_id: string; timestamp: number; ts_validation: boolean; }; }; }>;
} }
export function registerEIPValidator(service: EIPValidatorDef): void; export function registerEIPValidator(service: EIPValidatorDef): void;
export function registerEIPValidator(serviceId: string, service: EIPValidatorDef): void; export function registerEIPValidator(serviceId: string, service: EIPValidatorDef): void;
@ -338,9 +338,9 @@ export function delete_records(...args: any) {
} }
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<string>; export function validate(eip712_url: string, node: string, relay: string, config?: {ttl?: number}): Promise<ValidateResult>;
export function validate(peer: FluencePeer, eip712_url: string, node: string, relay: string, config?: {ttl?: number}): Promise<string>; export function validate(peer: FluencePeer, eip712_url: string, node: string, relay: string, config?: {ttl?: number}): Promise<ValidateResult>;
export function validate(...args: any) { export function validate(...args: any) {
let script = ` let script = `

View File

@ -61,26 +61,22 @@ async function main() {
console.log("Lets validate proposal %s, which is old and should fail.", EIP712_URL); console.log("Lets validate proposal %s, which is old and should fail.", EIP712_URL);
let doc_val = await validate(EIP712_URL, poc_topologies[0].node_id, poc_topologies[0].relay_id); let doc_val = await validate(EIP712_URL, poc_topologies[0].node_id, poc_topologies[0].relay_id);
// if (doc_val.stderr.length > 0) {} // if (doc_val.stderr.length > 0) {}
console.log("doc val: ", doc_val); console.log("signed eip validation result: ", doc_val);
rec_count = await get_record_count(poc_topologies[0].node_id, poc_topologies[0].relay_id);
console.log("record count: ", rec_count);
let records = await get_records(poc_topologies[0].node_id, poc_topologies[0].relay_id); let records = await get_records(poc_topologies[0].node_id, poc_topologies[0].relay_id);
if (records.stderr.length > 0) { if (records.stderr.length > 0) {
console.log("Records fetch error: ", records.stderr); console.log("We should have one record in the node db but do not: ", records.stderr);
} }
else { else {
console.log("record length: ", records.stdout.length); console.log("We should have one record in the node db and have %s record(s).", records.stdout.length);
} }
console.log("We know from the EIP document that the snapshot is 9278489, which i sued as a unique key in the sqlite db.")
// verify test console.log(" and we can call individual recirds by snapshot:")
// const address = ethers.utils.verifyMessage(resp_str, signed_response); let good_record = await get_record(9278489, poc_topologies[0].node_id, poc_topologies[0].relay_id);
// console.log("verify signature. peer_id: ", peer_id, " verified addr: ", address, " equal: ", peer_id === address); let bad_record = await get_record(92784890, poc_topologies[0].node_id, poc_topologies[0].relay_id);
console.log("result for call with 9278489: ", good_record);
// console.log(resp_str); console.log("result for call with bad 92784890: ", bad_record);
return; return;
} }

View File

@ -1,47 +0,0 @@
/*
* Copyright 2021 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Fluence, KeyPair } from "@fluencelabs/fluence";
import { krasnodar } from "@fluencelabs/fluence-network-environment";
import { validate } from "./_aqua/demo_validation";
const NODE_ID: string = "12D3KooWFCY8xqebtZqNeiA5took71bUNAedzCCDuCuM1QTdTbWT";
const RELAY_ID: string = krasnodar[0].peerId;
const EIP_URL: string = "https://ipfs.fleek.co/ipfs/QmWGzSQFm57ohEq2ATw4UNHWmYU2HkMjtedcNLodYywpmS";
async function main() {
await Fluence.start({
connectTo: krasnodar[0],
});
console.log("application started");
console.log("peer id is: ", Fluence.getStatus().peerId);
console.log("relay is: ", Fluence.getStatus().relayPeerId, "\n\n");
const result = await validate(EIP_URL, NODE_ID, RELAY_ID);
console.log("validation result: ", result);
await Fluence.stop();
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error('something went wrong: ', error);
process.exit(1);
});

Binary file not shown.

View File

@ -116,25 +116,21 @@ async function startFluencePeer(skBytes: Uint8Array): Promise<void> {
async function main() { async function main() {
console.log("Snapshot service node running with ...")
let wallet = new ethers.Wallet(SecretKey); let wallet = new ethers.Wallet(SecretKey);
console.log("wallet from sk: ", wallet.address); console.log("wallet from sk: ", wallet.address);
console.log("wallet pk: ", wallet.publicKey); console.log("wallet pk: ", wallet.publicKey);
const skBytes: Uint8Array = ethers.utils.arrayify(SecretKey); const skBytes: Uint8Array = ethers.utils.arrayify(SecretKey);
console.log("arrayify: ", skBytes);
await startFluencePeer(skBytes); await startFluencePeer(skBytes);
console.log("PeerId: ", Fluence.getStatus().peerId); console.log("PeerId: ", Fluence.getStatus().peerId);
console.log("Relay id: ", Fluence.getStatus().relayPeerId); console.log("Relay id: ", Fluence.getStatus().relayPeerId);
// let peer = Fluence.getPeer(); // register the Aqua-programmable services
// console.log(peer);
// console.log(Fluence.KeyPair);
registerEIPValidator("EIPValidator", new EIPValidator()); registerEIPValidator("EIPValidator", new EIPValidator());
registerDataProvider("DataProvider", new DataProvider); registerDataProvider("DataProvider", new DataProvider);
console.log("crtl-c to exit"); console.log("crtl-c to exit");
// await Fluence.stop(); // await Fluence.stop();
} }