apxtrib/api/models/Nations.js

227 lines
7.4 KiB
JavaScript
Raw Normal View History

2023-03-27 05:52:21 +00:00
const bcrypt = require("bcrypt");
const fs = require("fs-extra");
const glob = require("glob");
const jwt = require("jwt-simple");
const axios = require("axios");
2023-04-13 05:46:35 +00:00
const path=require('path');
2023-04-27 04:17:20 +00:00
const conf=require('../../nationchains/tribes/conf.json')
2023-04-13 05:46:35 +00:00
const Odmdb = require('./Odmdb.js');
// lowercase 1st letter is normal
const towns = require('./Towns.js');
const pagans = require('./Pagans.js');
2023-01-22 09:53:09 +00:00
/*
Blockchain manager
2023-03-27 05:52:21 +00:00
* Manage network directory of nations and towns
2023-01-22 09:53:09 +00:00
* 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
*/
2023-04-13 05:46:35 +00:00
const Nations = {};
Nations.init = () => {
console.group("init Nations");
2023-03-27 05:52:21 +00:00
};
2023-04-13 05:46:35 +00:00
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
2023-04-27 04:17:20 +00:00
* Each object to sync have a /idx/conf.json with key lastupdate = timestamp last update
2023-04-13 05:46:35 +00:00
* 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={}
2023-04-27 04:17:20 +00:00
glob.sync('nationchains/**/idx/conf.json').forEach(f=>{
2023-04-13 05:46:35 +00:00
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
2023-04-27 04:17:20 +00:00
const knowntowns =fs.readJsonSync('nationchains/towns/idx/towns_townId_all.json');
2023-04-13 05:46:35 +00:00
let promiselistblock=[]
let towidlist=[]
Object.keys(knowntowns).forEach(townid=>{
// identify the town with the highest block to update town
2023-04-27 04:17:20 +00:00
promiselistblock.push(axios.get(`${knowntowns[townid].url}/blocks/idx/conf.json`));
2023-04-13 05:46:35 +00:00
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=>{
2023-04-27 04:17:20 +00:00
promiselistref.push(axios.get(`${knowntowns[selectedtown].url}/${obj}/idx/conf.json`));
2023-04-13 05:46:35 +00:00
})
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
}
2023-04-27 04:17:20 +00:00
Nations.update=(nationsource)=>{
2023-04-13 05:46:35 +00:00
/**
* Update object nation with last update
*/
}
Nations.synchronize = () => {
2023-03-27 05:52:21 +00:00
/*
2023-04-13 05:46:35 +00:00
Run process to communicate with a list of towns to update network and transaction
*/
2023-03-27 05:52:21 +00:00
//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(
2023-04-27 04:17:20 +00:00
`${conf.tribes}/${conf.mayorId}/nationchains/nodes/${conf.rootURL}`,
2023-03-27 05:52:21 +00:00
"utf-8"
);
} catch (err) {
console.log("first init");
}
2023-04-27 04:17:20 +00:00
const loginsglob = fs.readJsonSync(`${conf.tmp}/loginsglob.json`, "utf-8");
2023-03-27 05:52:21 +00:00
currentinstance.logins = Object.keys(loginsglob);
currentinstance.tribeids = [...new Set(Object.values(loginsglob))];
currentinstance.instanceknown = glob.Sync(
2023-04-27 04:17:20 +00:00
`${conf.tribes}/${conf.mayorId}/nationchains/nodes/*`
2023-03-27 05:52:21 +00:00
);
//Save it
fs.outputJsonSync(
2023-04-27 04:17:20 +00:00
`${conf.tribes}/${conf.mayorId}/nationchains/nodes/${conf.rootURL}`,
2023-03-27 05:52:21 +00:00
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
2023-04-13 05:46:35 +00:00
// in any case rerun Nations.synchronize()
2023-03-27 05:52:21 +00:00
currentinstance.instanceknown.forEach((u) => {
2023-04-27 04:17:20 +00:00
if (u != conf.rootURL) {
2023-03-27 05:52:21 +00:00
//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(
2023-04-27 04:17:20 +00:00
`${conf.tribes}/${conf.mayorId}/nationchains/nodes/${u}`,
2023-03-27 05:52:21 +00:00
(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(
2023-04-27 04:17:20 +00:00
`${conf.tribes}/${conf.mayorId}/nationchains/nodes/${k}`,
2023-03-27 05:52:21 +00:00
initcurrentinstance,
"utf-8"
);
}
});
}
//save with info
fs.outputJson(
2023-04-27 04:17:20 +00:00
`${conf.tribes}/${conf.mayorId}/nationchains/nodes/${u}`,
2023-03-27 05:52:21 +00:00
data
);
}
);
})
.catch((err) => {
//Not available
data.negatifupdate += 1;
data.lasttimeupdate = Date.now();
fs.outputJson(
2023-04-27 04:17:20 +00:00
`${conf.tribes}/${conf.mayorId}/nationchains/nodes/${u}`,
2023-03-27 05:52:21 +00:00
data
);
});
}
});
2023-01-22 09:53:09 +00:00
};
2023-04-13 05:46:35 +00:00
Nations.create = (conf) => {
2023-03-27 05:52:21 +00:00
/*
@conf from a nationchains/socialworld/setup/townSetup {object, nationName, townName, dns}
@return
*/
const res = {};
2023-04-13 05:46:35 +00:00
if (conf.object=="towns"){
Odmdb.create("nationchains/socialworld/objects","towns",conf);
2023-03-27 05:52:21 +00:00
}
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
};
2023-01-22 09:53:09 +00:00
2023-04-27 04:17:20 +00:00
module.exports = Nations;