Remove forum-network stub code
This commit is contained in:
parent
7e74773242
commit
36acc56fa2
|
@ -1,67 +0,0 @@
|
||||||
import { Action } from '../display/action.js';
|
|
||||||
import {
|
|
||||||
Message, PostMessage, PeerMessage, messageFromJSON,
|
|
||||||
} from './message.js';
|
|
||||||
import { NetworkNode } from './network-node.js';
|
|
||||||
import { randomID } from '../../util/helpers.js';
|
|
||||||
|
|
||||||
export class ForumNode extends NetworkNode {
|
|
||||||
constructor(name, scene) {
|
|
||||||
super(name, scene);
|
|
||||||
this.actions = {
|
|
||||||
...this.actions,
|
|
||||||
storePost: new Action('store post', scene),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process a message from the queue
|
|
||||||
async processMessage(messageJson) {
|
|
||||||
try {
|
|
||||||
await Message.verify(messageJson);
|
|
||||||
} catch (e) {
|
|
||||||
await this.actions.processMessage.log(this, this, 'invalid signature', null, '-x');
|
|
||||||
console.log(`${this.name}: received message with invalid signature`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { publicKey } = messageJson;
|
|
||||||
const message = messageFromJSON(messageJson);
|
|
||||||
|
|
||||||
if (message instanceof PostMessage) {
|
|
||||||
await this.processPostMessage(publicKey, message.content);
|
|
||||||
} else if (message instanceof PeerMessage) {
|
|
||||||
await this.processPeerMessage(publicKey, message.content);
|
|
||||||
} else {
|
|
||||||
// Unknown message type
|
|
||||||
// Penalize sender for wasting our time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process an incoming post, received by whatever means
|
|
||||||
async processPost(authorId, post) {
|
|
||||||
if (!post.id) {
|
|
||||||
post.id = randomID();
|
|
||||||
}
|
|
||||||
await this.actions.storePost.log(this, this);
|
|
||||||
// this.forumView.addPost(authorId, post.id, post, stake);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process a post we received in a message
|
|
||||||
async processPostMessage(authorId, { post, stake }) {
|
|
||||||
this.processPost(authorId, post, stake);
|
|
||||||
await this.broadcast(
|
|
||||||
new PeerMessage({
|
|
||||||
posts: [{ authorId, post, stake }],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process a message we receive from a peer
|
|
||||||
async processPeerMessage(peerId, { posts }) {
|
|
||||||
// We are trusting that the peer verified the signatures of the posts they're forwarding.
|
|
||||||
// We could instead have the peer forward the signed messages and re-verify them.
|
|
||||||
for (const { authorId, post, stake } of posts) {
|
|
||||||
this.processPost(authorId, post, stake);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
import { CryptoUtil } from '../supporting/crypto.js';
|
|
||||||
import { PostContent } from '../supporting/post-content.js';
|
|
||||||
|
|
||||||
export class Message {
|
|
||||||
constructor(content) {
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
async sign({ publicKey, privateKey }) {
|
|
||||||
this.publicKey = await CryptoUtil.exportKey(publicKey);
|
|
||||||
// Call toJSON before signing, to match what we'll later send
|
|
||||||
this.signature = await CryptoUtil.sign(this.contentToJSON(), privateKey);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async verify({ content, publicKey, signature }) {
|
|
||||||
return CryptoUtil.verify(content, publicKey, signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
contentToJSON() {
|
|
||||||
return this.content;
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON() {
|
|
||||||
return {
|
|
||||||
type: this.type,
|
|
||||||
content: this.contentToJSON(),
|
|
||||||
publicKey: this.publicKey,
|
|
||||||
signature: this.signature,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PostMessage extends Message {
|
|
||||||
type = 'post';
|
|
||||||
|
|
||||||
constructor({ post, stake }) {
|
|
||||||
super({
|
|
||||||
post: PostContent.fromJSON(post),
|
|
||||||
stake,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
contentToJSON() {
|
|
||||||
return {
|
|
||||||
post: this.content.post.toJSON(),
|
|
||||||
stakeAmount: this.content.stake,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PeerMessage extends Message {
|
|
||||||
type = 'peer';
|
|
||||||
}
|
|
||||||
|
|
||||||
const messageTypes = new Map([
|
|
||||||
['post', PostMessage],
|
|
||||||
['peer', PeerMessage],
|
|
||||||
]);
|
|
||||||
|
|
||||||
export const messageFromJSON = ({ type, content }) => {
|
|
||||||
const MessageType = messageTypes.get(type) || Message;
|
|
||||||
// const messageContent = MessageType.contentFromJSON(content);
|
|
||||||
return new MessageType(content);
|
|
||||||
};
|
|
|
@ -1,58 +0,0 @@
|
||||||
import { Actor } from '../display/actor.js';
|
|
||||||
import { Action } from '../display/action.js';
|
|
||||||
import { CryptoUtil } from '../util/crypto.js';
|
|
||||||
import { PrioritizedQueue } from '../util/prioritized-queue.js';
|
|
||||||
|
|
||||||
export class NetworkNode extends Actor {
|
|
||||||
constructor(name, scene) {
|
|
||||||
super(name, scene);
|
|
||||||
this.queue = new PrioritizedQueue();
|
|
||||||
this.actions = {
|
|
||||||
peerMessage: new Action('peer message', scene),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a signing key pair and connect to the network
|
|
||||||
async initialize(forumNetwork) {
|
|
||||||
this.keyPair = await CryptoUtil.generateAsymmetricKey();
|
|
||||||
this.forumNetwork = forumNetwork.addNode(this);
|
|
||||||
this.status.set('Initialized');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send a message to all other nodes in the network
|
|
||||||
async broadcast(message) {
|
|
||||||
await message.sign(this.keyPair);
|
|
||||||
const otherForumNodes = this.forumNetwork
|
|
||||||
.listNodes()
|
|
||||||
.filter((forumNode) => forumNode.keyPair.publicKey !== this.keyPair.publicKey);
|
|
||||||
for (const forumNode of otherForumNodes) {
|
|
||||||
// For now just call receiveMessage on the target node
|
|
||||||
// await this.actions.peerMessage.log(this, forumNode, null, message.content);
|
|
||||||
await this.actions.peerMessage.log(this, forumNode);
|
|
||||||
await forumNode.receiveMessage(JSON.stringify(message.toJSON()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform minimal processing to ingest a message.
|
|
||||||
// Enqueue it for further processing.
|
|
||||||
async receiveMessage(messageStr) {
|
|
||||||
const messageJson = JSON.parse(messageStr);
|
|
||||||
// const senderReputation = this.forumView.getReputation(messageJson.publicKey) || 0;
|
|
||||||
const senderReputation = 0;
|
|
||||||
this.queue.add(messageJson, senderReputation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process next highest priority message in the queue
|
|
||||||
async processNextMessage() {
|
|
||||||
const messageJson = this.queue.pop();
|
|
||||||
if (!messageJson) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this.processMessage(messageJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process a message from the queue
|
|
||||||
// async processMessage(messageJson) {
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
export class Network {
|
|
||||||
constructor() {
|
|
||||||
this.nodes = new Map();
|
|
||||||
}
|
|
||||||
|
|
||||||
addNode(node) {
|
|
||||||
this.nodes.set(node.keyPair.publicKey, node);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
listNodes() {
|
|
||||||
return Array.from(this.nodes.values());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,7 +29,6 @@
|
||||||
</ol>
|
</ol>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="./tests/forum-network.test.html">Forum Network</a></li>
|
|
||||||
<li><a href="./tests/vm.test.html">VM</a></li>
|
<li><a href="./tests/vm.test.html">VM</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
<script src="https://unpkg.com/chai/chai.js"></script>
|
<script src="https://unpkg.com/chai/chai.js"></script>
|
||||||
<script type="module" src="./scripts/availability.test.js"></script>
|
<script type="module" src="./scripts/availability.test.js"></script>
|
||||||
<script type="module" src="./scripts/business.test.js"></script>
|
<script type="module" src="./scripts/business.test.js"></script>
|
||||||
<script type="module" src="./scripts/forum-network.test.js"></script>
|
|
||||||
<script type="module" src="./scripts/mocha.test.js"></script>
|
<script type="module" src="./scripts/mocha.test.js"></script>
|
||||||
<script type="module" src="./scripts/validation-pool.test.js"></script>
|
<script type="module" src="./scripts/validation-pool.test.js"></script>
|
||||||
<script type="module" src="./scripts/vm.test.js"></script>
|
<script type="module" src="./scripts/vm.test.js"></script>
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Forum Network test</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="stylesheet" href="https://unpkg.com/mocha/mocha.css" />
|
|
||||||
<link type="text/css" rel="stylesheet" href="../index.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h2><a href="../">DGF Tests</a></h2>
|
|
||||||
<div id="mocha"></div>
|
|
||||||
<div id="scene"></div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/radash/10.7.0/radash.js"
|
|
||||||
integrity="sha512-S207zKWG3iqXqe6msO7/Mr8X3DzzF4u8meFlokHjGtBPTGUhgzVo0lpcqEy0GoiMUdcoct+H+SqzoLsxXbynzg=="
|
|
||||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/10.2.0/mocha.min.js"
|
|
||||||
integrity="sha512-jsP/sG70bnt0xNVJt+k9NxQqGYvRrLzWhI+46SSf7oNJeCwdzZlBvoyrAN0zhtVyolGcHNh/9fEgZppG2pH+eA=="
|
|
||||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.3.7/chai.min.js"
|
|
||||||
integrity="sha512-tfLUmTr4u39/6Pykb8v/LjLaQ9u/uSgbHtZXFCtT9bOsZd1ZPZabIrwhif/YzashftTOhwwQUC0cQyrnIC1vEQ=="
|
|
||||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
||||||
<script type="module" src="./scripts/forum-network.test.js"></script>
|
|
||||||
<script defer class="mocha-init">
|
|
||||||
mocha.setup({
|
|
||||||
ui: 'bdd',
|
|
||||||
});
|
|
||||||
window.should = chai.should();
|
|
||||||
</script>
|
|
|
@ -1,81 +0,0 @@
|
||||||
import { Box } from '../../classes/display/box.js';
|
|
||||||
import { Scene } from '../../classes/display/scene.js';
|
|
||||||
import { PostContent } from '../../classes/supporting/post-content.js';
|
|
||||||
import { Expert } from '../../classes/actors/expert.js';
|
|
||||||
import { ForumNode } from '../../classes/forum-network/forum-node.js';
|
|
||||||
import { Network } from '../../classes/forum-network/network.js';
|
|
||||||
import { mochaRun, randomID } from '../../util/helpers.js';
|
|
||||||
import { delayOrWait } from '../../classes/display/controls.js';
|
|
||||||
|
|
||||||
describe('Forum Network', function tests() {
|
|
||||||
this.timeout(0);
|
|
||||||
|
|
||||||
let scene;
|
|
||||||
let author1;
|
|
||||||
let author2;
|
|
||||||
let forumNetwork;
|
|
||||||
let forumNode1;
|
|
||||||
let forumNode2;
|
|
||||||
let forumNode3;
|
|
||||||
let processInterval;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
const rootElement = document.getElementById('scene');
|
|
||||||
const rootBox = new Box('rootBox', rootElement).flex();
|
|
||||||
|
|
||||||
scene = new Scene('Forum Network test', rootBox).withSequenceDiagram();
|
|
||||||
|
|
||||||
author1 = await new Expert(null, 'author1', scene).initialize();
|
|
||||||
author2 = await new Expert(null, 'author2', scene).initialize();
|
|
||||||
|
|
||||||
forumNetwork = new Network();
|
|
||||||
|
|
||||||
forumNode1 = await new ForumNode('node1', scene).initialize(
|
|
||||||
forumNetwork,
|
|
||||||
);
|
|
||||||
forumNode2 = await new ForumNode('node2', scene).initialize(
|
|
||||||
forumNetwork,
|
|
||||||
);
|
|
||||||
forumNode3 = await new ForumNode('node3', scene).initialize(
|
|
||||||
forumNetwork,
|
|
||||||
);
|
|
||||||
|
|
||||||
processInterval = setInterval(async () => {
|
|
||||||
await forumNode1.processNextMessage();
|
|
||||||
await forumNode2.processNextMessage();
|
|
||||||
await forumNode3.processNextMessage();
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(() => {
|
|
||||||
clearInterval(processInterval);
|
|
||||||
});
|
|
||||||
|
|
||||||
// const blockchain = new Blockchain();
|
|
||||||
|
|
||||||
specify('Author can submit a post to the network', async () => {
|
|
||||||
const post1 = new PostContent({ message: 'hi' });
|
|
||||||
post1.id = randomID();
|
|
||||||
const post2 = new PostContent({ message: 'hello' }).addCitation(
|
|
||||||
post1.id,
|
|
||||||
1.0,
|
|
||||||
);
|
|
||||||
|
|
||||||
await delayOrWait(1000);
|
|
||||||
await author1.submitPostViaNetwork(
|
|
||||||
forumNode1,
|
|
||||||
post1,
|
|
||||||
50,
|
|
||||||
);
|
|
||||||
await delayOrWait(1000);
|
|
||||||
await author2.submitPostViaNetwork(
|
|
||||||
forumNode2,
|
|
||||||
post2,
|
|
||||||
100,
|
|
||||||
);
|
|
||||||
|
|
||||||
await delayOrWait(1000);
|
|
||||||
}).timeout(10000);
|
|
||||||
});
|
|
||||||
|
|
||||||
mochaRun();
|
|
Loading…
Reference in New Issue