mirror of
https://github.com/fluencelabs/eip712-validation-node
synced 2025-05-28 07:31:19 +00:00
update readme, cleanup comments
This commit is contained in:
parent
2c59a94479
commit
4f163db19b
81
README.md
81
README.md
@ -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).
|
||||
|
||||
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).
|
||||
|
||||
@ -73,23 +73,88 @@ TODO:
|
||||
|
||||
## 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
|
||||
npm i
|
||||
npm run compile-aqua
|
||||
npm start
|
||||
```
|
||||
|
||||
Or run with
|
||||
And the ensuing terminal output should look like this:
|
||||
|
||||
```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.
|
||||
|
@ -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:
|
||||
snapshot_id: u64
|
||||
event_address: string
|
||||
@ -14,8 +29,8 @@ data DBResult:
|
||||
stdout: []DBRecord
|
||||
|
||||
service EIPValidator("EIPValidator"):
|
||||
eip712_validation_string(eip_str: string, peer_id: string) -> string
|
||||
eip712_validation_url(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) -> ValidationResult
|
||||
|
||||
service DataProvider("DataProvider"):
|
||||
get_records() -> DBResult
|
||||
@ -24,7 +39,7 @@ service DataProvider("DataProvider"):
|
||||
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:
|
||||
res <- EIPValidator.eip712_validation_url(eip712_url, node)
|
||||
<- res
|
||||
|
@ -17,8 +17,8 @@ import {
|
||||
// Services
|
||||
|
||||
export interface EIPValidatorDef {
|
||||
eip712_validation_string: (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'>) => 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'>) => { 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(serviceId: string, service: EIPValidatorDef): void;
|
||||
@ -338,9 +338,9 @@ export function delete_records(...args: any) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function validate(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<string>;
|
||||
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<ValidateResult>;
|
||||
export function validate(peer: FluencePeer, eip712_url: string, node: string, relay: string, config?: {ttl?: number}): Promise<ValidateResult>;
|
||||
export function validate(...args: any) {
|
||||
|
||||
let script = `
|
||||
|
@ -61,26 +61,22 @@ async function main() {
|
||||
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);
|
||||
// if (doc_val.stderr.length > 0) {}
|
||||
console.log("doc val: ", doc_val);
|
||||
|
||||
rec_count = await get_record_count(poc_topologies[0].node_id, poc_topologies[0].relay_id);
|
||||
console.log("record count: ", rec_count);
|
||||
console.log("signed eip validation result: ", doc_val);
|
||||
|
||||
let records = await get_records(poc_topologies[0].node_id, poc_topologies[0].relay_id);
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// verify test
|
||||
// const address = ethers.utils.verifyMessage(resp_str, signed_response);
|
||||
// console.log("verify signature. peer_id: ", peer_id, " verified addr: ", address, " equal: ", peer_id === address);
|
||||
|
||||
// console.log(resp_str);
|
||||
|
||||
console.log("We know from the EIP document that the snapshot is 9278489, which i sued as a unique key in the sqlite db.")
|
||||
console.log(" and we can call individual recirds by snapshot:")
|
||||
let good_record = await get_record(9278489, poc_topologies[0].node_id, poc_topologies[0].relay_id);
|
||||
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("result for call with bad 92784890: ", bad_record);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -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.
@ -116,25 +116,21 @@ async function startFluencePeer(skBytes: Uint8Array): Promise<void> {
|
||||
|
||||
async function main() {
|
||||
|
||||
console.log("Snapshot service node running with ...")
|
||||
let wallet = new ethers.Wallet(SecretKey);
|
||||
console.log("wallet from sk: ", wallet.address);
|
||||
console.log("wallet pk: ", wallet.publicKey);
|
||||
|
||||
const skBytes: Uint8Array = ethers.utils.arrayify(SecretKey);
|
||||
console.log("arrayify: ", skBytes);
|
||||
|
||||
await startFluencePeer(skBytes);
|
||||
|
||||
|
||||
console.log("PeerId: ", Fluence.getStatus().peerId);
|
||||
console.log("Relay id: ", Fluence.getStatus().relayPeerId);
|
||||
|
||||
// let peer = Fluence.getPeer();
|
||||
// console.log(peer);
|
||||
// console.log(Fluence.KeyPair);
|
||||
|
||||
// register the Aqua-programmable services
|
||||
registerEIPValidator("EIPValidator", new EIPValidator());
|
||||
registerDataProvider("DataProvider", new DataProvider);
|
||||
|
||||
console.log("crtl-c to exit");
|
||||
// await Fluence.stop();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user