-
Notifications
You must be signed in to change notification settings - Fork 2
P2P #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
gluax
wants to merge
99
commits into
main
Choose a base branch
from
feature/p2p
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
P2P #22
Changes from 13 commits
Commits
Show all changes
99 commits
Select commit
Hold shift + click to select a range
8ccd71f
theoritcally works, not sure why type issues
gluax 55d3444
piping without it-pipe
gluax ce284be
add some todos so I don't forget
gluax 00537f2
some cleanup, and saving of known peers
gluax 8f2ad61
logging
gluax e87c575
clean up saving and loading peers
gluax b008da5
fix some typing issues
gluax c61ed73
fix saving of peers
gluax a23c86b
remove old comments
gluax 18b434f
some slight more cleanup
gluax 1f8657f
changes so far, have a question
gluax fa91005
aggregation
gluax ddfc429
merge main, config handling
gluax 0d3d41e
make suggested changes
gluax cd0f1aa
uses fs promises
gluax cee0f4f
feat: allow node consensus of chosen median
gluax 1ab178e
feat: Add logging to p2p aggregation utils, add p2p module
gluax b3dd758
p2p module uses p2p
gluax 7dfbac0
fix: fix some string bugs in aggrate, and timing of methods called in…
gluax 3273a78
feat: p2p aggregator use Big.js for better decimal tracking
gluax d28ff98
fix: fix equality check of medians with bigjs eq method
gluax b8bc9a6
feat: send median to contract
gluax ba7eb11
Merge branch 'main' of github.com:fluxprotocol/fpo-node into feature/p2p
gluax 76a5a3b
feat: started deviation, started fixing some issues with sending/reci…
gluax 2c5300f
WIP: Easier usage
FranklinWaller 87c0ae7
WIP: Sending transaction to chain
FranklinWaller 4986a63
feat(p2p): add protection for double processing
FranklinWaller a665f71
fix: generate valid sigs, and correctly grab roundid
gluax 467d36f
feat: add p2p module deviation checking
gluax 38debba
chore: clean up todo comment
gluax b6c7029
feat: sqlite logging
gluax 073fbb9
feat: changes to p2p from admin audit
gluax df7dde2
feat: creates pairs if not yet made, as well as finish changes for th…
gluax 582f3c1
fix: call right provider in evm call
gluax f475a9c
fix: p2p call deployOracle
mennatnaga 5e4b197
refactor: check oracle status before deploying
mennatnaga c79cbdd
chore: add config files
mennatnaga 0139f0a
chore: add createPeer.ts
mennatnaga 4e5b540
fix: assert creator matches wallet public address before deployOracle
mennatnaga 08b2134
fix: sort reports
mennatnaga 8d26afe
fix: delete outdated (round) reports
mennatnaga 5e7569f
fix: reselect leader when stuck
mennatnaga 044fe07
fix: reuse old report data, but use relected round id
gluax 1987fac
fix: require unique objects in Sets, sign fresh data
mennatnaga 74a2f8d
fix: switch transmitters
mennatnaga 3a46100
refactor: clear reports after each round, assume all sigs needed
mennatnaga 339780c
feat: initial p2p fuzzing
gluax eaf8194
fix: merge upstream changes
gluax 9ce0bab
refactor: allow transmitting less signatures
mennatnaga 74285cb
chore: fuzzing code clean up
gluax fba3850
fix: non creator nodes now wait for pairs to be created instead of ex…
gluax 0b2f65e
fix: fetch round before handling reports
mennatnaga 3b74729
fix: rm fetching rounds, increase delay between queue batches
mennatnaga 64f6285
node and report versioning
gluax 7374005
Merge branch 'feature/p2p' of github.com:fluxprotocol/fpo-node into f…
gluax 4a5fd0c
fix: resubmit unsuccessful rounds
mennatnaga 220e769
feat(fuzzing): change workers out with clustering
gluax 13f8b3a
fix: waiting on creator to deploy oracle & fix p2p versioning checks
gluax ab51a40
feat(fuzz): start working on random nodes disconnecting
gluax 1cea595
fix: filter old unsuccessful sigs
mennatnaga 86d001f
fix: fix p2p versioning issues, fix random disconnects in fuzzing
gluax 8b1132d
Merge branch 'feature/p2p' of github.com:fluxprotocol/fpo-node into f…
gluax a03c0d5
fix: version checking on p2p, and p2p fuzzing version handling
gluax 5aad90c
feat: fuzz report versions, add some new options for timings
gluax b7700c6
feat: add more fuzzing pair generation
gluax 4f5860d
feat: clean up pair generation duplicates, config for interval and de…
gluax 0c6f391
fix remove duplicate pairs
gluax 18fe96c
fix: set roundId only after successful transmission
mennatnaga c43e7d7
fix: move p2p version check, temporarily disable version sharing in p…
gluax 2b90f33
fix: wait for enough signatures
mennatnaga d839862
fix: check resolved rounds to avoid double transmit
mennatnaga 60a2d4a
prevent transmitting 0s
gluax 5ee7992
fix: transmit 0s and merge upstream
gluax c7097d5
feat: better log tracking for fuzzing runs
gluax 04c5d37
fix: Use the correct local address for reconnecting
gluax 15e99f9
fix: update peers to avoid choosing a disconnected leader, skip itera…
mennatnaga 3c1c5b4
feat: re-enable version sending between p2p nodes
gluax 7724101
chore: add postinstall command for moving fuzzer to separate repo
gluax a72fb25
fix: fix type module generation
gluax 5f63d67
fix: include package json for types generation
gluax 5f08e94
fix: need both js and .d.ts files for fuzzer
gluax cb7d059
fix: generate .d.ts files
gluax 478ab34
fix: types generation including json files
gluax 455133d
fix: exclude output dir from types generation
gluax 9555f96
fix: add include back
gluax 9059bfc
fix: json files included locally but not for deps
gluax 284c466
fix: explicitly include all json files
gluax a88a7b6
refactor: adjust gasLimit for ganache
mennatnaga 3cad051
feat: support multiple networks in p2p module
jamesondh d1a6cfe
refactor: skip less iterations
mennatnaga 8130f17
feat: add getMinSignersForPair()
mennatnaga f21b6ca
refactor: remove fuzzer to another repo
gluax 38c9905
feat: change nodes to just log they are out of date and not quit, as …
gluax 2613804
fix: fix logging of versions in recieving
gluax 54e0900
fix: trying to prevent version recieved from constantly going off.
gluax b9aeaf5
feat: clean up sending report version
gluax b8a1a22
feat: adding a trace to help debug why p2p-version is called so many …
gluax 7a23de5
feat: more cleanup on version sending, still trying to debug multiple…
gluax 2dfc5a3
refactor: waiting for sigs
mennatnaga File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| import { CreateOptions } from "libp2p"; | ||
| import Communicator from './communication'; | ||
| import TCP from "libp2p-tcp"; | ||
| const Mplex = require("libp2p-mplex"); // no ts support yet :/ | ||
| import { NOISE } from "@chainsafe/libp2p-noise"; | ||
| import BufferList from "bl/BufferList"; | ||
| import { fromString } from 'uint8arrays/from-string'; | ||
|
|
||
| export async function start_p2p(addresses: CreateOptions, peers_file: string): Promise<Communicator> { | ||
| const p2p = new Communicator( | ||
| { | ||
| ...addresses, | ||
| modules: { | ||
| transport: [TCP], | ||
| streamMuxer: [Mplex], | ||
| connEncryption: [NOISE], | ||
| } | ||
| }, | ||
| peers_file | ||
| ); | ||
| await p2p.init(); | ||
|
|
||
| return p2p; | ||
| } | ||
|
|
||
| export async function elect_leader(p2p: Communicator): Promise<string> { | ||
| // method should maybe be moved to Communicator? | ||
| let peers = Array.from(p2p._peers); | ||
| peers.push(p2p._node_addr); | ||
| peers = peers.sort(); | ||
| return peers[0]; | ||
| } | ||
|
|
||
| export function median(list: number[]): number { | ||
| list = list.sort(); | ||
|
|
||
| let mid_point = list.length / 2 ; | ||
|
|
||
| if (mid_point % 2) { | ||
| return (list[mid_point - 1] + list[mid_point]) / 2; | ||
| } else { | ||
| return list[mid_point]; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| export async function aggregate(p2p: Communicator, data_to_send: string) { | ||
| await p2p.start(); | ||
| let received: number[] = []; | ||
| let med: number = 0; | ||
| let leader: string = ''; | ||
|
|
||
| p2p.handle_incoming('/elected/leader', async (source: AsyncIterable<Uint8Array | BufferList>) => { | ||
| for await (const msg of source) { | ||
| let elected = msg.toString(); | ||
| // check if this node is the leader. | ||
| if (elected === leader) { | ||
| // send data to contract. | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| p2p.handle_incoming('/send/data', async (source: AsyncIterable<Uint8Array | BufferList>) => { | ||
| for await (const msg of source) { | ||
| received.push(parseInt(msg.toString())); | ||
| if (received.length = p2p._peers.size) { | ||
| med = median(received); | ||
| leader = await elect_leader(p2p); | ||
| p2p.send('/elected/leader', [fromString(leader)]); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| p2p.send('/send/data', [fromString(data_to_send)]); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| import Libp2p, { Connection, create, CreateOptions, Libp2pOptions } from "libp2p"; | ||
| import TCP from "libp2p-tcp"; | ||
| const Mplex = require("libp2p-mplex"); // no ts support yet :/ | ||
| import { NOISE } from "@chainsafe/libp2p-noise"; | ||
| import { Multiaddr } from "multiaddr"; | ||
| import PeerId from "peer-id"; | ||
| import BufferList from "bl/BufferList"; | ||
| import { existsSync, readFileSync, writeFileSync } from "fs"; | ||
|
|
||
| import logger from "../services/LoggerService"; | ||
|
|
||
| async function* createAsyncIterable(syncIterable: Uint8Array[]) { | ||
| for (const elem of syncIterable) { | ||
| yield elem; | ||
| } | ||
| } | ||
|
|
||
| async function attempt<R>(comm: Communicator, def: R, attempt: (node: Libp2p) => Promise<R>): Promise<R> { | ||
| if (comm._node === undefined) { | ||
| logger.error('The communication node has not been started.'); | ||
| return def; | ||
| } else { | ||
| return attempt(comm._node); | ||
| } | ||
| } | ||
|
|
||
| export default class Communicator { | ||
| _connections: Set<Connection> = new Set(); | ||
| _options: Libp2pOptions & CreateOptions; | ||
| _node?: Libp2p; | ||
| _node_addr: string; | ||
| _peers: Set<string>; | ||
| _peers_file: string; | ||
| _retry: Set<string> = new Set(); | ||
|
|
||
| constructor(config?: Libp2pOptions & CreateOptions, peers_file?: string) { | ||
| if (config === undefined) { | ||
| this._options = { | ||
| addresses: { | ||
| listen: ['/ip4/0.0.0.0/tcp/0'] | ||
| }, | ||
| modules: { | ||
| transport: [TCP], | ||
| streamMuxer: [Mplex], | ||
| connEncryption: [NOISE], | ||
| } | ||
| }; | ||
| } else { | ||
| this._options = config; | ||
| } | ||
|
|
||
| if (peers_file === undefined) { | ||
| this._peers_file = 'peers.json'; | ||
| this._peers = new Set(); | ||
| } else { | ||
| this._peers_file = peers_file; | ||
| this._peers = this.load_peers(); | ||
| } | ||
|
|
||
| this._node_addr = ''; | ||
| } | ||
|
|
||
| async init(): Promise<void> { | ||
| this._node = await create(this._options); | ||
| } | ||
|
|
||
| async retry(): Promise<void> { | ||
| attempt(this, null, async () => { | ||
| for (const peer of this._retry) { | ||
| if (await this.connect(new Multiaddr(peer))) { | ||
| this._retry.delete(peer); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| async start(): Promise<[Multiaddr, PeerId] | void> { | ||
| return attempt(this, undefined, async (node: Libp2p) => { | ||
| await node.start(); | ||
|
|
||
| for (const peer of this._peers) { | ||
| if (!await this.connect(new Multiaddr(peer))) { | ||
| this._retry.add(peer); | ||
| } | ||
| } | ||
|
|
||
| this._node_addr = node.multiaddrs[0].toString(); | ||
|
|
||
| return [ | ||
| node.multiaddrs[0], | ||
| node.peerId, | ||
| ]; | ||
| }) | ||
| } | ||
|
|
||
| async stop(): Promise<void> { | ||
| attempt(this, false, async (node: Libp2p) => { | ||
| try { | ||
| for (const peer of this._peers) { | ||
| node.hangUp(peer); | ||
| } | ||
|
|
||
| this.save_peers(); | ||
|
|
||
| await node.stop(); | ||
|
|
||
| return true; | ||
| } catch (error) { | ||
| logger.error(`Node failed to stop with error '${error}'.`); | ||
| return false; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| async connect(ma: Multiaddr): Promise<boolean> { | ||
| return attempt(this, false, async (node: Libp2p) => { | ||
| try { | ||
| this._peers.add(ma.toString()); | ||
| const conn = await node.dial(ma); | ||
| if (conn !== undefined) { | ||
| this._connections.add(conn); | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } catch (error) { | ||
| logger.error(`Node failed to connect to ${ma} with error '${error}'.`); | ||
| return false; | ||
| } | ||
| }); | ||
|
|
||
| } | ||
|
|
||
| async connect_from_details(ip: string, address: string, transport: string, port: string, peerID: string): Promise<boolean> { | ||
| return attempt(this, false, async (node: Libp2p) => { | ||
| const mas = `/${ip}/${address}/${transport}/${port}/p2p/${peerID}`; | ||
| const ma = new Multiaddr(`/${ip}/${address}/${transport}/${port}/p2p/${peerID}`); | ||
|
|
||
| try { | ||
| if (!this._peers.has(mas)) { | ||
| this._peers.add(mas); | ||
| } | ||
|
|
||
| const conn = await node.dial(ma); | ||
| if (conn !== undefined) { | ||
| this._connections.add(conn); | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } catch (error) { | ||
| this._peers.delete(mas); | ||
| logger.error(`Node failed to connect to ${ma} with error '${error}'.`); | ||
| return false; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| async handle_incoming(protocol: string, callback: (source: AsyncIterable<Uint8Array | BufferList>) => Promise<void>): Promise<void> { | ||
| await attempt(this, null, async (node: Libp2p) => { | ||
| node.handle(protocol, async ({ stream }) => { | ||
| await callback(stream.source); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| async send(protocol: string, data: Uint8Array[]): Promise<void> { | ||
| attempt(this, null, async () => { | ||
| for (const connection of this._connections) { | ||
| const { stream } = await connection.newStream(protocol); | ||
| await stream.sink(createAsyncIterable(data)); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| save_peers(): void { | ||
| let peers = Array.from(this._peers).sort(); | ||
|
|
||
| const json = JSON.stringify(peers, null, 4); | ||
| try { | ||
| writeFileSync(this._peers_file, json); | ||
| } catch (error) { | ||
| logger.error(`Node failed to save peers with error '${error}'.`); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| load_peers(): Set<string> { | ||
| if (!existsSync(this._peers_file)) { | ||
| return new Set(); | ||
| } | ||
|
|
||
| try { | ||
| const json = readFileSync(this._peers_file, 'utf-8'); | ||
|
gluax marked this conversation as resolved.
Outdated
|
||
| const peers_list: string[] = JSON.parse(json); | ||
|
|
||
| let peers: Set<string> = new Set(); | ||
| for (const peer of peers_list) { | ||
| peers.add(peer); | ||
| } | ||
|
|
||
| return peers; | ||
| } catch (error) { | ||
| logger.error(`Node failed to load peers with error '${error}'.`); | ||
| return new Set(); | ||
| } | ||
|
|
||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.