227 lines
7.5 KiB
JavaScript
Executable File
227 lines
7.5 KiB
JavaScript
Executable File
const bcrypt = require("bcrypt");
|
|
const fs = require("fs-extra");
|
|
const glob = require("glob");
|
|
const jwt = require("jwt-simple");
|
|
const axios = require("axios");
|
|
const path=require('path');
|
|
//const config = require("../tribes/townconf.js");
|
|
const Odmdb = require('./Odmdb.js');
|
|
// lowercase 1st letter is normal
|
|
const towns = require('./Towns.js');
|
|
const pagans = require('./Pagans.js');
|
|
/*
|
|
Blockchain manager
|
|
* Manage network directory of nations and towns
|
|
* read Blockchain and search,
|
|
* submit a transaction (now) or contract (futur) to store from userA.pubkey to userB.pubkey a number of AXESS
|
|
* mine to be able to register a block and create AXESS
|
|
* manage APIXP rules 20 M APIXP 1AXESS = 1 block validation
|
|
* manage contract = action if something appened validate by a proof of work
|
|
*/
|
|
const Nations = {};
|
|
Nations.init = () => {
|
|
console.group("init Nations");
|
|
};
|
|
|
|
Nations.updateChains = async (newtown) =>{
|
|
/**
|
|
* @newtown {object} optional to request a registration in the nationchain network
|
|
* if newtown exist then it send a request to update itself else it just refresh from existing town.
|
|
* Check public nationchains are up to date from the existing list of towns
|
|
* Each object to sync have a /index/config.json with key lastupdate = timestamp last update
|
|
* tribes is not synchonized and contain private information
|
|
* A town is a network node of the nationchains and allow to synchronize new
|
|
*/
|
|
const res= {status:400};
|
|
const ref2update={}
|
|
glob.sync('nationchains/**/index/config.json').forEach(f=>{
|
|
const ref=fs.readJsonSync(f)
|
|
ref2update[path.basename(ref.schema,'.json')]=ref.lastupdate;
|
|
})
|
|
console.log(ref2update)
|
|
// Get list of town to check n of them have fresh update
|
|
const knowntowns =fs.readJsonSync('nationchains/towns/index/towns_townId_all.json');
|
|
let promiselistblock=[]
|
|
let towidlist=[]
|
|
Object.keys(knowntowns).forEach(townid=>{
|
|
// identify the town with the highest block to update town
|
|
promiselistblock.push(axios.get(`${knowntowns[townid].url}/blocks/index/config.json`));
|
|
townidlistblock.push(townid)
|
|
});
|
|
let selectedtown=""
|
|
let blocnum=0
|
|
await Promise.all(promiselistblock)
|
|
.then(rep=>{
|
|
for (let pos=0;pos<townidlist.length;pos++){
|
|
if (rep[pos].blocnum > blocnum) {
|
|
selectedtown=townidlist[pos]
|
|
blocnum=rep[pos].blocnum
|
|
}
|
|
}
|
|
})
|
|
.catch(err=>{
|
|
console.log(err)
|
|
})
|
|
let promiselistref=[]
|
|
Object.keys(ref2update).forEach(ob=>{
|
|
promiselistref.push(axios.get(`${knowntowns[selectedtown].url}/${obj}/index/config.json`));
|
|
})
|
|
await Promise.all(promiselistref)
|
|
.then(rep=>{
|
|
for (let pos=0;pos<townidlist.length;pos++){
|
|
//si axios lastupdate > local lastupate => recupe _all et regenere tous les objets par ecrasement
|
|
}
|
|
})
|
|
.catch(err=>{
|
|
console.log(err)
|
|
})
|
|
return res
|
|
}
|
|
|
|
Nation.update=(nationsource)=>{
|
|
/**
|
|
* Update object nation with last update
|
|
*/
|
|
}
|
|
|
|
Nations.synchronize = () => {
|
|
/*
|
|
Run process to communicate with a list of towns to update network and transaction
|
|
*/
|
|
//update himself then send to other information
|
|
if (process.env.NODE_ENV != "prod") {
|
|
// Not concerned
|
|
return {};
|
|
}
|
|
const initcurrentinstance = {
|
|
fixedIP: "",
|
|
lastblocknumber: 0,
|
|
firsttimeupdate: 0,
|
|
lastimeupdate: 0,
|
|
positifupdate: 0,
|
|
negatifupdate: 0,
|
|
pubkeyadmin: "",
|
|
tribeids: [],
|
|
logins: [],
|
|
knowninstance: [],
|
|
};
|
|
let currentinstance = initcurrentinstance;
|
|
try {
|
|
currentinstance = fs.readFileSync(
|
|
`${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`,
|
|
"utf-8"
|
|
);
|
|
} catch (err) {
|
|
console.log("first init");
|
|
}
|
|
const loginsglob = fs.readJsonSync(`${config.tmp}/loginsglob.json`, "utf-8");
|
|
currentinstance.logins = Object.keys(loginsglob);
|
|
currentinstance.tribeids = [...new Set(Object.values(loginsglob))];
|
|
currentinstance.instanceknown = glob.Sync(
|
|
`${config.tribes}/${config.mayorId}/nationchains/nodes/*`
|
|
);
|
|
//Save it
|
|
fs.outputJsonSync(
|
|
`${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`,
|
|
currentinstance
|
|
);
|
|
// proof of work
|
|
// try to find a key based on last block with difficulty
|
|
// if find then send to all for update and try to get token
|
|
// in any case rerun Nations.synchronize()
|
|
currentinstance.instanceknown.forEach((u) => {
|
|
if (u != config.rootURL) {
|
|
//send currentinstance info and get back state of
|
|
axios
|
|
.post(`https://${u}/nationchains/push`, currentinstance)
|
|
.then((rep) => {
|
|
newdata = rep.payload.moreinfo;
|
|
//Available update info
|
|
fs.readJson(
|
|
`${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`,
|
|
(err, data) => {
|
|
if (err) {
|
|
data.negatifupdate += 1;
|
|
data.lasttimeupdate = Date.now();
|
|
} else {
|
|
data.positifupdate += 1;
|
|
data.lastimeupdate = Date.now();
|
|
data.tribeids = newdata.tribeids;
|
|
data.logins = newdata.logins;
|
|
data.lastblocknumber = newdata.lastblocknumber;
|
|
newdata.knowninstance.forEach((k) => {
|
|
if (!data.knowninstance.includes(k)) {
|
|
data.knowninstance.push(k);
|
|
//init the domain for next update
|
|
initcurrentinstance.firsttimeupdate = Date.now();
|
|
fs.outputJson(
|
|
`${config.tribes}/${config.mayorId}/nationchains/nodes/${k}`,
|
|
initcurrentinstance,
|
|
"utf-8"
|
|
);
|
|
}
|
|
});
|
|
}
|
|
//save with info
|
|
fs.outputJson(
|
|
`${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`,
|
|
data
|
|
);
|
|
}
|
|
);
|
|
})
|
|
.catch((err) => {
|
|
//Not available
|
|
data.negatifupdate += 1;
|
|
data.lasttimeupdate = Date.now();
|
|
fs.outputJson(
|
|
`${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`,
|
|
data
|
|
);
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
Nations.create = (conf) => {
|
|
/*
|
|
@conf from a nationchains/socialworld/setup/townSetup {object, nationName, townName, dns}
|
|
@return
|
|
*/
|
|
const res = {};
|
|
if (conf.object=="towns"){
|
|
Odmdb.create("nationchains/socialworld/objects","towns",conf);
|
|
}
|
|
const nation_town = fs.readJsonSync(
|
|
"./nationchains/socialworld/objects/towns/searchindex/towns_nationId_townId.json"
|
|
);
|
|
if (!ObjectKeys(nation_town).includes(conf.nationName)) {
|
|
res.status = 404;
|
|
res.info = `your nationName ${conf.nationName} does not exist you have to choose an existing one`;
|
|
return res;
|
|
}
|
|
if (nation_town[conf.nationName].includes(conf.townName)) {
|
|
res.status = 409;
|
|
res.info = `This conf.townName already exist you have to find a unique town name per nation`;
|
|
return res;
|
|
}
|
|
const towndata = {
|
|
uuid: conf.townName,
|
|
nationid: conf.nationName,
|
|
url: `${conf.townName}.${conf.nationName}.${conf.dns}`,
|
|
status: (conf.dns=="unchain")? "unchain" : "tochain",
|
|
};
|
|
const metatown=fs.readJsonSync('./nationchains/socialworld/metaobject/towns.json');
|
|
Odmdb.add(objectpath, towns, metatown,towndata)
|
|
|
|
fs.outputJsonSync(
|
|
`./nationchains/socialworld/objects/towns/${townName}.json`,
|
|
towndata
|
|
);
|
|
res.status=200
|
|
res.info=`${townName} create for ${nationName} nation`;
|
|
return res
|
|
};
|
|
|
|
module.exports = Nationchains;
|