Added table view
This commit is contained in:
parent
acda73fff4
commit
4c9cee9963
|
@ -48,3 +48,5 @@ If this is the only scenario in which new rep tokens are minted, and from then o
|
|||
then we probably want each token to store information about the history of its value.
|
||||
At a minimum this can be a list where each item includes the identifier of the corresponding validation pool, and the resulting increment/decrement of token value.
|
||||
Each validation pool can then keep a record of the reputation staked by each voter, and the identifier of the corresponding post.
|
||||
|
||||
---
|
||||
|
|
|
@ -6,6 +6,7 @@ export class Actor {
|
|||
this.status = this.scene.addDisplayValue(`${this.name} status`);
|
||||
this.status.set('Created');
|
||||
this.values = new Map();
|
||||
this.valueFunctions = new Map();
|
||||
this.active = 0;
|
||||
this.scene.registerActor(this);
|
||||
}
|
||||
|
@ -50,13 +51,16 @@ export class Actor {
|
|||
return this;
|
||||
}
|
||||
|
||||
addValue(label) {
|
||||
addValue(label, fn) {
|
||||
this.values.set(label, this.scene.addDisplayValue(`${this.name} ${label}`));
|
||||
if (fn) {
|
||||
this.valueFunctions.set(label, fn);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
async setValue(label, value) {
|
||||
if (typeof value === 'number') {
|
||||
if (typeof value === 'number' && value.toString().length > 6) {
|
||||
value = value.toFixed(2);
|
||||
}
|
||||
let displayValue = this.values.get(label);
|
||||
|
@ -70,4 +74,26 @@ export class Actor {
|
|||
displayValue.set(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
async computeValues() {
|
||||
for (const [label, fn] of this.valueFunctions.entries()) {
|
||||
const displayValue = this.values.get(label);
|
||||
let value = fn();
|
||||
if (typeof value === 'number' && value.toString().length > 6) {
|
||||
value = value.toFixed(2);
|
||||
}
|
||||
if (value !== displayValue.get()) {
|
||||
await this.scene.sequence.log(`note over ${this.name} : ${label} = ${value}`);
|
||||
}
|
||||
displayValue.set(value);
|
||||
}
|
||||
}
|
||||
|
||||
getValuesMap() {
|
||||
return new Map(Array.from(this.values.entries())
|
||||
.map(([key, displayValue]) => [key, {
|
||||
name: displayValue.getName(),
|
||||
value: displayValue.get(),
|
||||
}]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,4 +20,8 @@ export class DisplayValue {
|
|||
get() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,50 @@ class MermaidDiagram {
|
|||
}
|
||||
}
|
||||
|
||||
class Table {
|
||||
constructor(box) {
|
||||
this.box = box;
|
||||
this.columns = [];
|
||||
this.rows = [];
|
||||
this.table = box.el.appendChild(document.createElement('table'));
|
||||
this.headings = this.table.appendChild(document.createElement('tr'));
|
||||
}
|
||||
|
||||
setColumns(columns) {
|
||||
if (JSON.stringify(columns) === JSON.stringify(this.columns)) {
|
||||
return;
|
||||
}
|
||||
if (this.columns.length) {
|
||||
this.table.innerHTML = '';
|
||||
this.headings = this.table.appendChild(document.createElement('tr'));
|
||||
this.columns = [];
|
||||
}
|
||||
this.columns = columns;
|
||||
for (const { title } of columns) {
|
||||
const heading = document.createElement('th');
|
||||
this.headings.appendChild(heading);
|
||||
heading.innerHTML = title ?? '';
|
||||
}
|
||||
if (this.rows.length) {
|
||||
const { rows } = this;
|
||||
this.rows = [];
|
||||
for (const row of rows) {
|
||||
this.addRow(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addRow(rowMap) {
|
||||
this.rows.push(rowMap);
|
||||
const row = this.table.appendChild(document.createElement('tr'));
|
||||
for (const { key } of this.columns) {
|
||||
const value = rowMap.get(key);
|
||||
const cell = row.appendChild(document.createElement('td'));
|
||||
cell.innerHTML = value ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Scene {
|
||||
constructor(name, rootBox) {
|
||||
this.name = name;
|
||||
|
@ -46,6 +90,7 @@ export class Scene {
|
|||
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||
this.topSection = this.box.addBox('Top section').flex();
|
||||
this.displayValuesBox = this.topSection.addBox('Values');
|
||||
this.middleSection = this.box.addBox('Middle section').flex();
|
||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||
this.actors = new Set();
|
||||
|
||||
|
@ -86,6 +131,16 @@ export class Scene {
|
|||
return this;
|
||||
}
|
||||
|
||||
withTable() {
|
||||
if (this.table) {
|
||||
return this;
|
||||
}
|
||||
const box = this.middleSection.addBox('Table');
|
||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||
this.table = new Table(box);
|
||||
return this;
|
||||
}
|
||||
|
||||
async addActor(name) {
|
||||
const actor = new Actor(name, this);
|
||||
if (this.sequence) {
|
||||
|
@ -130,4 +185,22 @@ export class Scene {
|
|||
this.sequence.inSection--;
|
||||
this.sequence.log('end');
|
||||
}
|
||||
|
||||
stateToTable(label) {
|
||||
const row = new Map();
|
||||
const columns = [];
|
||||
columns.push({ key: 'seqNum', title: '#' });
|
||||
row.set('seqNum', this.table.rows.length + 1);
|
||||
row.set('label', label);
|
||||
for (const actor of this.actors) {
|
||||
for (const [aKey, { name, value }] of actor.getValuesMap()) {
|
||||
const key = `${actor.name}:${aKey}`;
|
||||
columns.push({ key, title: name });
|
||||
row.set(key, value);
|
||||
}
|
||||
}
|
||||
columns.push({ key: 'label', title: '' });
|
||||
this.table.setColumns(columns);
|
||||
this.table.addRow(row);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,11 @@ export class ValidationPool extends ReputationHolder {
|
|||
amount: this.mintedValue * (1 - params.stakeForAuthor),
|
||||
tokenId: this.tokenId,
|
||||
});
|
||||
|
||||
// Keep a record of voters and their votes
|
||||
const voter = this.bench.voters.get(reputationPublicKey) ?? new Voter(reputationPublicKey);
|
||||
voter.addVoteRecord(this);
|
||||
this.bench.voters.set(reputationPublicKey, voter);
|
||||
}
|
||||
|
||||
getTokenLossRatio() {
|
||||
|
@ -171,6 +176,12 @@ export class ValidationPool extends ReputationHolder {
|
|||
voter.addVoteRecord(this);
|
||||
this.bench.voters.set(reputationPublicKey, voter);
|
||||
}
|
||||
|
||||
// Update computed display values
|
||||
for (const voter of this.bench.voters.values()) {
|
||||
const actor = this.scene.findActor((a) => a.reputationPublicKey === voter.reputationPublicKey);
|
||||
await actor.computeValues();
|
||||
}
|
||||
}
|
||||
|
||||
applyTokenLocking() {
|
||||
|
@ -266,5 +277,17 @@ export class ValidationPool extends ReputationHolder {
|
|||
}
|
||||
|
||||
console.log('pool complete');
|
||||
|
||||
// Update computed display values
|
||||
for (const voter of this.bench.voters.values()) {
|
||||
const actor = this.scene.findActor((a) => a.reputationPublicKey === voter.reputationPublicKey);
|
||||
await actor.computeValues();
|
||||
}
|
||||
await this.bench.computeValues();
|
||||
if (this.forum) {
|
||||
await this.forum.computeValues();
|
||||
}
|
||||
|
||||
this.scene.stateToTable(`validation pool ${this.name} complete`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,10 @@ a:visited {
|
|||
svg {
|
||||
width: 800px;
|
||||
}
|
||||
.hidden {
|
||||
/* display: none; */
|
||||
/* visibility: hidden; */
|
||||
th {
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
}
|
||||
td {
|
||||
background-color: #0c2025;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
const scene = (window.scene = new Scene('Availability test', rootBox));
|
||||
scene.withSequenceDiagram();
|
||||
scene.withFlowchart();
|
||||
scene.withTable();
|
||||
|
||||
const experts = (window.experts = []);
|
||||
const newExpert = async () => {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
const scene = (window.scene = new Scene('Forum test', rootBox));
|
||||
scene.withSequenceDiagram();
|
||||
scene.withFlowchart();
|
||||
scene.withTable();
|
||||
|
||||
scene.addDisplayValue('c3. stakeForAuthor').set(params.stakeForAuthor);
|
||||
scene.addDisplayValue('q2. revaluationLimit').set(params.revaluationLimit);
|
||||
|
@ -48,22 +49,19 @@
|
|||
const expert2 = await newExpert();
|
||||
const expert3 = await newExpert();
|
||||
|
||||
const updateDisplayValues = async () => {
|
||||
bench.addValue('total rep', () => bench.reputation.getTotal());
|
||||
forum.addValue('total value', () => forum.getTotalValue());
|
||||
|
||||
for (const expert of experts) {
|
||||
await expert.setValue(
|
||||
'rep',
|
||||
bench.reputation.valueOwnedBy(expert.reputationPublicKey),
|
||||
);
|
||||
expert.addValue('rep', () => bench.reputation.valueOwnedBy(expert.reputationPublicKey));
|
||||
}
|
||||
await bench.setValue('total rep', bench.reputation.getTotal());
|
||||
await forum.setValue('total value', forum.getTotalValue());
|
||||
};
|
||||
|
||||
const updateDisplayValuesAndDelay = async (delayMs) => {
|
||||
await updateDisplayValues();
|
||||
await delay(delayMs ?? DEFAULT_DELAY_INTERVAL);
|
||||
};
|
||||
|
||||
scene.stateToTable('Initial state');
|
||||
|
||||
await updateDisplayValuesAndDelay();
|
||||
|
||||
await scene.startSection();
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
const rootBox = new Box('rootBox', rootElement).flex();
|
||||
|
||||
const scene = (window.scene = new Scene('Validation Pool test', rootBox));
|
||||
await scene.withSequenceDiagram();
|
||||
scene.withSequenceDiagram();
|
||||
scene.withTable();
|
||||
const expert1 = (window.expert1 = await new Expert(
|
||||
'Expert1',
|
||||
scene,
|
||||
|
@ -31,25 +32,6 @@
|
|||
const forum = (window.forum = new Forum('Forum', scene));
|
||||
const bench = (window.bench = new Bench(forum, 'Bench', scene));
|
||||
|
||||
const updateDisplayValues = async () => {
|
||||
await expert1.setValue(
|
||||
'rep',
|
||||
bench.reputation.valueOwnedBy(expert1.reputationPublicKey),
|
||||
);
|
||||
await expert2.setValue(
|
||||
'rep',
|
||||
bench.reputation.valueOwnedBy(expert2.reputationPublicKey),
|
||||
);
|
||||
await bench.setValue('total rep', bench.reputation.getTotal());
|
||||
// With params.lockingTimeExponent = 0 and params.activeVoterThreshold = null,
|
||||
// these next 3 propetries are all equal to total rep
|
||||
// await bench.setValue('available rep', bench.reputation.getTotalAvailable());
|
||||
// await bench.setValue('active rep', bench.getActiveReputation());
|
||||
// await bench.setValue('active available rep', bench.getActiveAvailableReputation());
|
||||
await scene.sequence.render();
|
||||
};
|
||||
|
||||
updateDisplayValues();
|
||||
await delay(1000);
|
||||
|
||||
// First expert can self-approve
|
||||
|
@ -75,7 +57,6 @@
|
|||
}
|
||||
await delay(1000);
|
||||
await pool.evaluateWinningConditions(); // Vote passes
|
||||
await updateDisplayValues();
|
||||
await delay(1000);
|
||||
}
|
||||
|
||||
|
@ -88,7 +69,6 @@
|
|||
});
|
||||
await delay(1000);
|
||||
await pool.evaluateWinningConditions(); // Quorum not met!
|
||||
await updateDisplayValues();
|
||||
await delay(1000);
|
||||
} catch (e) {
|
||||
if (e.message.match(/Quorum is not met/)) {
|
||||
|
@ -113,13 +93,8 @@
|
|||
});
|
||||
await delay(1000);
|
||||
await pool.evaluateWinningConditions(); // Stake passes
|
||||
await updateDisplayValues();
|
||||
await delay(1000);
|
||||
}
|
||||
|
||||
await updateDisplayValues();
|
||||
|
||||
scene.deactivateAll();
|
||||
|
||||
await updateDisplayValues();
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue