lisk-framework
Version:
Lisk blockchain application platform
108 lines • 5.44 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.PoSMethod = void 0;
const lisk_utils_1 = require("@liskhq/lisk-utils");
const base_method_1 = require("../base_method");
const constants_1 = require("./constants");
const genesis_1 = require("./stores/genesis");
const staker_1 = require("./stores/staker");
const validator_1 = require("./stores/validator");
const name_1 = require("./stores/name");
const utils_1 = require("./utils");
const eligible_validators_1 = require("./stores/eligible_validators");
class PoSMethod extends base_method_1.BaseMethod {
init(moduleName, config, internalMethod, tokenMethod) {
this._moduleName = moduleName;
this._config = config;
this._tokenMethod = tokenMethod;
this._internalMethod = internalMethod;
}
async isNameAvailable(methodContext, name) {
const nameSubStore = this.stores.get(name_1.NameStore);
if (name.length > this._config.maxLengthName || name.length < 1 || !(0, utils_1.isUsername)(name)) {
return false;
}
const isRegistered = await nameSubStore.has(methodContext, Buffer.from(name));
if (isRegistered) {
return false;
}
return true;
}
async getStaker(methodContext, address) {
const stakerSubStore = this.stores.get(staker_1.StakerStore);
const stakerData = await stakerSubStore.get(methodContext, address);
return stakerData;
}
async getValidator(methodContext, address) {
const validatorSubStore = this.stores.get(validator_1.ValidatorStore);
const validator = await validatorSubStore.get(methodContext, address);
return validator;
}
getRoundLength(_methodContext) {
return this._config.roundLength;
}
getNumberOfActiveValidators(_methodContext) {
return this._config.numberActiveValidators;
}
async updateSharedRewards(context, generatorAddress, tokenID, reward) {
const validatorStore = this.stores.get(validator_1.ValidatorStore);
const validator = await validatorStore.get(context, generatorAddress);
if (validator.totalStake === BigInt(0)) {
return;
}
const { q96 } = lisk_utils_1.math;
const rewardQ = q96(reward);
const commissionQ = q96(BigInt(validator.commission));
const rewardFractionQ = q96(BigInt(1)).sub(commissionQ.div(q96(BigInt(10000))));
const selfStakeQ = q96(validator.selfStake);
const totalStakesQ = q96(validator.totalStake);
const matchingCoefficientIndex = validator.sharingCoefficients.findIndex(coefficient => coefficient.tokenID.equals(tokenID));
const index = matchingCoefficientIndex > -1
? matchingCoefficientIndex
: validator.sharingCoefficients.length;
if (matchingCoefficientIndex < 0) {
validator.sharingCoefficients[index] = { tokenID, coefficient: q96(BigInt(0)).toBuffer() };
}
const oldSharingCoefficient = q96(validator.sharingCoefficients[index].coefficient);
const sharingCoefficientIncrease = rewardQ.muldiv(rewardFractionQ, totalStakesQ);
const sharedRewards = sharingCoefficientIncrease.mul(totalStakesQ.sub(selfStakeQ)).ceil();
const cappedSharedRewards = sharedRewards > reward ? reward : sharedRewards;
await this._tokenMethod.lock(context, generatorAddress, this._moduleName, tokenID, cappedSharedRewards);
const newSharingCoefficient = oldSharingCoefficient.add(sharingCoefficientIncrease);
validator.sharingCoefficients[index].coefficient = newSharingCoefficient.toBuffer();
validator.sharingCoefficients.sort((a, b) => a.tokenID.compare(b.tokenID));
await validatorStore.set(context, generatorAddress, validator);
}
async getRoundNumberFromHeight(methodContext, height) {
const { height: genesisHeight } = await this.stores
.get(genesis_1.GenesisDataStore)
.get(methodContext, constants_1.EMPTY_KEY);
return Math.ceil((height - genesisHeight) / this._config.roundLength);
}
async isEndOfRound(methodContext, height) {
const { height: genesisHeight } = await this.stores
.get(genesis_1.GenesisDataStore)
.get(methodContext, constants_1.EMPTY_KEY);
return (height - genesisHeight) % this._config.roundLength === 0;
}
async unbanValidator(methodContext, address) {
const validatorSubStore = this.stores.get(validator_1.ValidatorStore);
const validator = await validatorSubStore.get(methodContext, address);
if (!validator.isBanned) {
throw new Error('The specified validator is not banned.');
}
if (validator.reportMisbehaviorHeights.length >= this._config.reportMisbehaviorLimitBanned) {
throw new Error('Validator exceeded the maximum allowed number of misbehaviors and is permanently banned.');
}
validator.isBanned = false;
await validatorSubStore.set(methodContext, address, validator);
await this.stores
.get(eligible_validators_1.EligibleValidatorsStore)
.update(methodContext, address, BigInt(0), validator);
}
async getLockedStakedAmount(ctx, address) {
return this._internalMethod.getLockedStakedAmount(ctx, address);
}
}
exports.PoSMethod = PoSMethod;
//# sourceMappingURL=method.js.map
;