@kadena/hardhat-chainweb
Version:
Hardhat plugin for Kadena's Chainweb network
153 lines • 5.29 kB
JavaScript
"use strict";
/* *************************************************************************** */
/* Chain */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Chain = void 0;
const async_lock_1 = __importDefault(require("async-lock"));
const network_contracts_js_1 = require("./network-contracts.js");
const logger_js_1 = require("./logger.js");
const create_hardhat_provider_js_1 = require("./create-hardhat-provider.js");
const lock = new async_lock_1.default();
class Chain {
get provider() {
if (!this._provider) {
throw new Error('Provider is not initialized');
}
return this._provider;
}
set adjacents(adjacents) {
this._adjacents = adjacents;
}
get adjacents() {
if (this._adjacents === null) {
throw new Error('Chain is not part of a network');
}
return this._adjacents;
}
constructor(config, logging = 'info') {
this.logging = logging;
const cid = config.chainwebChainId;
this.config = config;
this.logger = {
info: (msg) => logging !== 'none' ? (0, logger_js_1.logInfo)(logger_js_1.COLOR_PALETTE[cid % 6], cid, msg) : null,
error: (msg) => logging !== 'none' ? (0, logger_js_1.logError)(logger_js_1.COLOR_PALETTE[cid % 6], cid, msg) : null,
};
// set when the chain is added to the chainweb
this._adjacents = null;
// set when the ethers provider is created
this._provider = null;
// set when automining is enabled
this.autominer = null;
}
get cid() {
return this.config.chainwebChainId;
}
get url() {
return '';
}
get port() {
const url = new URL(this.url);
return url.port ? parseInt(url.port, 10) : 8454;
}
async getBlockNumber() {
// this.provider.getBlockNumber() is lagging. Maybe it caches internally or
// there's a race in the implementation?
// return await this.provider.getBlockNumber()
return parseInt(await this.provider.send('eth_blockNumber', []), 16);
}
async makeBlock() {
if (this.provider === null) {
throw new Error('Provider is not initialized');
}
return await this.provider.send('evm_mine', []);
}
async mineRequest() {
await lock.acquire('mine', async () => {
this.logger.info(`mining requested`);
await this.mine();
});
}
async mine() {
if (this.adjacents === null) {
throw new Error('Chain is not part of a network');
}
const cn = await this.getBlockNumber();
this.logger.info(`current height is ${cn}`);
for (const a of this.adjacents) {
const an = await a.getBlockNumber();
if (an < cn) {
await a.mine();
}
}
this.logger.info(`make new block`);
await this.makeBlock();
}
async hasPending() {
const ps = await this.provider.send('eth_getBlockTransactionCountByNumber', ['pending']);
return ps > 0;
}
async runPending() {
const pending = await this.hasPending();
if (pending) {
await this.mineRequest();
}
}
async initializeCidContract() {
await this.provider.send('hardhat_setCode', [
network_contracts_js_1.CHAIN_ID_ADDRESS,
network_contracts_js_1.CHAIN_ID_BYTE_CODE,
]);
const hex = '0x' + this.cid.toString(16).padStart(64, '0');
await this.provider.send('hardhat_setStorageAt', [
network_contracts_js_1.CHAIN_ID_ADDRESS,
'0x0',
hex,
]);
}
async initializeVerificationPrecompile() {
await this.provider.send('hardhat_setCode', [
network_contracts_js_1.VERIFY_ADDRESS,
network_contracts_js_1.VERIFY_BYTE_CODE,
]);
}
async enableAutomine() {
if (!this.autominer) {
this.autominer = setInterval(() => this.runPending(), 100);
this.logger.info(`Automine enabled`);
}
}
async disableAutomine() {
if (this.autominer) {
clearInterval(this.autominer);
this.autominer = null;
this.logger.info(`Automine disabled`);
}
}
async start() {
// start hardhat network
// await this.startHardhatNetwork();
// create provider
try {
this._provider = await (0, create_hardhat_provider_js_1.createHardhatProvider)(this.config, this.logger);
await this._provider.send('eth_accounts', []);
}
catch (e) {
console.error(e);
}
// initialize system contracts
await this.initializeCidContract();
await this.initializeVerificationPrecompile();
// setup automining
await this.provider.send('evm_setAutomine', [false]);
await this.enableAutomine();
}
async stop() {
this.disableAutomine();
this._provider = null;
}
}
exports.Chain = Chain;
//# sourceMappingURL=chain.js.map