godprotocol
Version:
A distributed computing environment for Web 4.0 — integrating AI, decentralisation, and virtual computation.
215 lines (173 loc) • 5.68 kB
JavaScript
import Utils from "./Utils.js";
import Compiler from "aircode4";
import Chain from "./Chain.js";
import Virtual_machine from "./Virtual_machine.js";
import register from "godprotocol/callables/register.js";
import { hash } from "godprotocol/utils/hash.js";
class Account extends Utils {
constructor(name, options) {
super();
this.name = name;
this.options = options;
this.init = options?.init;
this.manager = options.manager;
this.vm = new Virtual_machine(this);
this.compiler = new Compiler(this);
}
load = async (payload, options) => {
let { address, sequence, compiler, from_reload, _id } = payload;
let phy = `${this.physical_address}/${address}`;
let chain = await this.chain.chain(phy);
if (compiler) {
let adr = `.codes/${phy}.air`;
!from_reload &&
(await (
await this.manager.ds.folder(`${adr}`, {
account: this.physical_address,
})
).write({ sequence, _id }));
sequence = await this.compiler.to_sequence(sequence, address);
sequence = sequence[0];
}
let res = await chain.add_config(sequence, { ...options, _id });
await this.manager.emit("on_load", payload);
return res;
};
run = async (payload, socket) => {
let { address, _id, env, config, thread, callback } = payload;
if (!config) {
let phy = `${this.physical_address}/${address}`;
let chain = await this.chain.chain(phy);
let folder = await chain.folder(".configs");
config = await folder.readone(_id ? { _id } : null);
if (!config) {
let code = await (
await this.manager.ds.folder(`.codes/${phy}`, {
account: this.physical_address,
})
).readone(_id ? { _id } : null);
if (code) {
code = code.sequence;
code = await this.compiler.to_sequence(code, address);
code = code[0];
config = code;
await this.load({ address, sequence: config, _id });
}
}
}
if (!config) {
return { message: "Code not found!" };
}
let result = await this.vm.nodelist(config);
let thread_id = await this.manager.load(result, this, {
spawn: thread && thread._id,
pointer: thread && thread.pointer,
callback: async (res) => {
await this.run_callback(res, { callback, socket });
},
});
if (env) {
this.vm.envs[thread_id] = env;
}
await this.manager.emit("on_run", payload);
return { thread_id, callback };
};
parse = async (payload) => {
let { address, query, retrieve, from } = payload;
if (!address) {
return {
message: "Invalid payload.",
};
}
let phy = `${this.physical_address}/${address}`;
if (from === ".codes") {
let res = await (
await this.manager.ds.folder(`.codes/${phy}.air`, {
account: this.physical_address,
})
).readone(query?.query, query?.options);
if (res) {
return { result: res.sequence, _id: res._id };
} else return { message: "Code not found" };
} else if (from === "thread") {
// is thread_id;
let thread_info = this.manager.accounts_pairs[this.name];
let thread = thread_info.threads[address];
return thread
? {
_id: thread._id,
status: thread.status,
spawn: thread.spawn,
callback: thread.callback,
pointer: thread.pointer,
total: thread.bullets.length,
}
: {};
}
let folder = await this.ds.folder(
phy,
from === "ram" ? null : { account: this.physical_address }
);
let result = await folder.readone(query.query, { ...query.options });
if (!result) return result;
if (from !== "ram") {
if (this.vm.datatypes.includes(result.type)) {
let obj = await this.vm.retrieve(result, true);
if (retrieve) {
result = await obj.to_address();
} else result.literal = await obj.literal();
} else if (retrieve) {
result = await this.vm.retrieve(result);
}
} else {
if (this.vm.datatypes.includes(result.type)) {
if (retrieve) {
result = await (await this.vm.cloth_content(result)).to_address();
} else
result.literal = await (
await this.vm.cloth_content(result)
).literal();
} else if (retrieve) {
result = await this.vm.cloth_content(result);
}
}
return result;
};
verify = async (password, init) => {
let passes = await this.ds.folder(`${this.physical_address}/__passwords`, {
account: this.physical_address,
});
passes.secrecy = true;
let pass = await passes.readone(),
passed = false;
if (pass) {
passed = pass.key === hash(password);
} else if (init) {
passed = await passes.write({ key: hash(password) });
}
if (init)
this.servers =
passed &&
(await this.manager.oracle.update_servers(
this.physical_address,
this.servers
));
return passed;
};
sync = async () => {
this.physical_address = `${"Accounts"}/${this.name}`;
this.chain = new Chain(`${this.physical_address}`, this);
this.ds = this.manager.ds;
let pass = this.options.password,
res = true;
if (pass) {
res = await this.verify(pass, this.is_init);
}
await register(this);
if (res) {
console.log(`Account:${this.name} initiation successful!`);
} else console.log(`Account:${this.name} initiation failed!`);
return res;
};
}
export default Account;