Files
sashimono/examples/crawler/app.js
2022-11-16 11:05:57 +05:30

137 lines
4.8 KiB
JavaScript

const { ContractInstanceManager } = require('./contract-instance-manager');
const evernode = require("evernode-js-client");
const process = require('process');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const args = process.argv.slice(2);
const tenantAddress = args[0] || "rKaXLGujsf8LokeQxG6TsoKVq8XWEMKpH";
const tenantSecret = args[1] || "ssorCEAHJFhZihUjCbx55j1mP6RnZ";
const intervalSec = (args[2] && parseInt(args[2])) || 60;
console.log(tenantAddress, intervalSec);
const registryAddress = "r3cNR2bdao1NyvQ5ZuQvCUgqkoWGmgF34E";
const evrIssuerAddress = "rfxLPXCcSmwR99dV97yFozBzrzpvCa2VCf";
const foundationAddress = "rppVLpTDks7tjAGw9TRcwqMGzuDvzV72Vh";
const foundationSecret = "shdAf9oUv1TLVTTR26Ke7w7Gv44HN";
const contractOwnerPrivateKey = "edfbbf5e66101cbf443c137b66c6b379bd4dfb8274015f7a0accd5cf3f4c640aa65cb83404120ac759609819591ef839b7d222c84f1f08b3012f490586159d2b50";
const contractOwnerPublicKey = "ed5cb83404120ac759609819591ef839b7d222c84f1f08b3012f490586159d2b50";
const contractBundle = 'contract-bundle.zip';
const logFile = 'crawler.log';
const statsFile = 'stats.log';
let instancesCreated = 0;
async function fundTenant(tenant) {
// Send evers to tenant if needed.
const lines = await tenant.xrplAcc.getTrustLines('EVR', evrIssuerAddress);
if (lines.length === 0 || parseInt(lines[0].balance) < 1) {
await tenant.xrplAcc.setTrustLine('EVR', evrIssuerAddress, "99999999");
await new evernode.XrplAccount(foundationAddress, foundationSecret).makePayment(tenantAddress, "100000", 'EVR', evrIssuerAddress);
}
}
function appendLog(type, msg) {
const str = '\n' + new Date().toUTCString() + '\n' + type + '\n' + JSON.stringify(msg) + '\n';
fs.appendFileSync(logFile, str);
}
function updateStats(instancesCreated) {
fs.writeFileSync(statsFile, JSON.stringify({
instancesCreated: instancesCreated
}))
}
async function acquireLease(tenant, host, instanceId, contractId, ownerPubKey) {
if ((host.maxInstances - host.activeInstances) > 0) {
try {
console.log(`Acquiring lease in Host ${host.address} (currently ${host.activeInstances} instances)`);
const result = await tenant.acquireLease(host.address, {
container_name: instanceId,
owner_pubkey: ownerPubKey,
contract_id: contractId,
image: "hp.0.6.0-ubt.20.04-njs.16",
config: {}
}, { timeout: 60000 });
console.log(`Tenant received instance '${result.instance.name}'`);
return result.instance;
}
catch (err) {
console.log("Tenant recieved acquire error: ", err)
appendLog('AcquireError ' + host.address, err);
}
}
else {
console.log(`Host ${host.address} full.`);
}
return null;
}
async function spawnOnRandomHost(registry, tenant) {
console.log("------------------------------------------");
console.log(new Date().toUTCString());
const hosts = await registry.getActiveHosts();
if (hosts.length > 0) {
const randomIndex = Math.floor(Math.random() * hosts.length);
const host = hosts[randomIndex];
const contractId = uuidv4();
const instance = await acquireLease(tenant, host, contractId, contractId, contractOwnerPublicKey)
if (instance) {
console.log(`Received instance at ${new Date().toUTCString()}`, instance);
const instanceMgr = new ContractInstanceManager(contractOwnerPrivateKey, instance.pubkey, instance.ip, instance.user_port, instance.contractId, contractBundle);
try {
await instanceMgr.deployContract();
console.log('Instance deployed at', new Date().toUTCString());
updateStats(++instancesCreated);
}
catch (err) {
console.log("Contract deployment error.", err);
appendLog('DeployError ' + instance.ip, err);
}
}
else {
console.log('Spawning skipped.');
}
}
else {
console.log("No active hosts.");
}
// Reschedule same call.
setTimeout(() => {
spawnOnRandomHost(registry, tenant);
}, intervalSec * 1000);
}
async function crawler() {
const xrplApi = new evernode.XrplApi('wss://hooks-testnet-v2.xrpl-labs.com');
evernode.Defaults.set({
registryAddress: registryAddress,
xrplApi: xrplApi
})
await xrplApi.connect();
const tenant = new evernode.TenantClient(tenantAddress, tenantSecret);
await tenant.connect();
await tenant.prepareAccount();
await fundTenant(tenant);
const registry = new evernode.RegistryClient();
await registry.connect()
// Recursive scheduled call.
spawnOnRandomHost(registry, tenant);
}
crawler();