Files
grin-web-wallet/scripts/consensus.js
2024-12-20 18:08:44 -08:00

1588 lines
39 KiB
JavaScript
Executable File

// Use strict
"use strict";
// Classes
// Consensus class
class Consensus {
// Public
// Initialize
static initialize() {
// Update saved wallet type and network type
Consensus.getWalletType();
Consensus.getNetworkType();
}
// Get wallet type
static getWalletType() {
// Check if consensus's wallet type doesn't exist
if(typeof Consensus.walletType === "undefined") {
// Check if not not a web worker and local storage is usable
if((typeof self === "undefined" || typeof WorkerGlobalScope === "undefined" || self instanceof WorkerGlobalScope === false) && typeof localStorage !== "undefined") {
// Get the saved wallet type
var walletType = localStorage.getItem(Consensus.WALLET_TYPE_LOCAL_STORAGE_NAME);
// Check if wallet type doesn't exist or isn't valid
if(walletType === Common.INVALID_LOCAL_STORAGE_ITEM || Number.isNaN(parseInt(walletType, Common.DECIMAL_NUMBER_BASE)) === true) {
// Set wallet type to the default wallet type
walletType = Consensus.DEFAULT_WALLET_TYPE;
}
// Otherwise
else {
// Get wallet type in the correct format
walletType = parseInt(walletType, Common.DECIMAL_NUMBER_BASE);
// Check if the wallet type doesn't exist
if(walletType < Consensus.MWC_WALLET_TYPE || walletType > Consensus.EPIC_WALLET_TYPE) {
// Set wallet type to the default wallet type
walletType = Consensus.DEFAULT_WALLET_TYPE;
}
}
}
// Otherwise
else {
// Set wallet type to the default wallet type
var walletType = Consensus.DEFAULT_WALLET_TYPE;
}
// Get URL parameters
var urlParameters = Common.getUrlParameters();
// Check if override wallet type exists
if(Consensus.OVERRIDE_WALLET_TYPE_URL_PARAMETER_NAME in urlParameters === true) {
// Check override wallet type
switch(urlParameters[Consensus.OVERRIDE_WALLET_TYPE_URL_PARAMETER_NAME]) {
// MWC wallet
case Consensus.WALLET_MWC_TEXT_VALUE:
// Set wallet type to MWC wallet type
walletType = Consensus.MWC_WALLET_TYPE;
// Break
break;
// GRIN wallet
case Consensus.WALLET_GRIN_TEXT_VALUE:
// Set wallet type to GRIN wallet type
walletType = Consensus.GRIN_WALLET_TYPE;
// Break
break;
// EPIC wallet
case Consensus.WALLET_EPIC_TEXT_VALUE:
// Set wallet type to EPIC wallet type
walletType = Consensus.EPIC_WALLET_TYPE;
// Break
break;
}
}
// Check if not not a web worker and local storage is usable
if((typeof self === "undefined" || typeof WorkerGlobalScope === "undefined" || self instanceof WorkerGlobalScope === false) && typeof localStorage !== "undefined") {
// Check if saved wallet type needs to be updated
if(walletType.toFixed() !== localStorage.getItem(Consensus.WALLET_TYPE_LOCAL_STORAGE_NAME)) {
// Try
try {
// Save wallet type in local storage
localStorage.setItem(Consensus.WALLET_TYPE_LOCAL_STORAGE_NAME, walletType.toFixed());
}
// Catch errors
catch(error) {
}
}
}
// Set consensus's wallet type
Consensus.walletType = walletType;
}
// Return consensus's wallet type
return Consensus.walletType;
}
// Get network type
static getNetworkType() {
// Check if consensus's network type doesn't exist
if(typeof Consensus.networkType === "undefined") {
// Check if not not a web worker and local storage is usable
if((typeof self === "undefined" || typeof WorkerGlobalScope === "undefined" || self instanceof WorkerGlobalScope === false) && typeof localStorage !== "undefined") {
// Get the saved network type
var networkType = localStorage.getItem(Consensus.NETWORK_TYPE_LOCAL_STORAGE_NAME);
// Check if network type doesn't exist or isn't valid
if(networkType === Common.INVALID_LOCAL_STORAGE_ITEM || Number.isNaN(parseInt(networkType, Common.DECIMAL_NUMBER_BASE)) === true) {
// Set network type to the default network type
networkType = Consensus.DEFAULT_NETWORK_TYPE;
}
// Otherwise
else {
// Get network type in the correct format
networkType = parseInt(networkType, Common.DECIMAL_NUMBER_BASE);
// Check if the network type doesn't exist
if(networkType < Consensus.MAINNET_NETWORK_TYPE || networkType > Consensus.TESTNET_NETWORK_TYPE) {
// Set network type to the default network type
networkType = Consensus.DEFAULT_NETWORK_TYPE;
}
}
}
// Otherwise
else {
// Set network type to the default network type
var networkType = Consensus.DEFAULT_NETWORK_TYPE;
}
// Get URL parameters
var urlParameters = Common.getUrlParameters();
// Check if override network type exists
if(Consensus.OVERRIDE_NETWORK_TYPE_URL_PARAMETER_NAME in urlParameters === true) {
// Check override network type
switch(urlParameters[Consensus.OVERRIDE_NETWORK_TYPE_URL_PARAMETER_NAME]) {
// Mainnet network
case Consensus.NETWORK_MAINNET_TEXT_VALUE:
// Set network type to mainnet network type
networkType = Consensus.MAINNET_NETWORK_TYPE;
// Break
break;
// Testnet network
case Consensus.NETWORK_TESTNET_TEXT_VALUE:
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Set network type to testnet network type
networkType = Consensus.TESTNET_NETWORK_TYPE;
// Break
break;
}
// Break
break;
// Floonet network
case Consensus.NETWORK_FLOONET_TEXT_VALUE:
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC or EPIC wallet
case Consensus.MWC_WALLET_TYPE:
case Consensus.EPIC_WALLET_TYPE:
// Set network type to testnet network type
networkType = Consensus.TESTNET_NETWORK_TYPE;
// Break
break;
}
// Break
break;
}
}
// Check if not not a web worker and local storage is usable
if((typeof self === "undefined" || typeof WorkerGlobalScope === "undefined" || self instanceof WorkerGlobalScope === false) && typeof localStorage !== "undefined") {
// Check if saved network type needs to be updated
if(networkType.toFixed() !== localStorage.getItem(Consensus.NETWORK_TYPE_LOCAL_STORAGE_NAME)) {
// Try
try {
// Save network type in local storage
localStorage.setItem(Consensus.NETWORK_TYPE_LOCAL_STORAGE_NAME, networkType.toFixed());
}
// Catch errors
catch(error) {
}
}
}
// Set consensus's network type
Consensus.networkType = networkType;
}
// Return consensus's network type
return Consensus.networkType;
}
// Wallet type to text
static walletTypeToText(walletType) {
// Check wallet type
switch(walletType) {
// MWC wallet type
case Consensus.MWC_WALLET_TYPE:
// Return MWC wallet text value
return Consensus.WALLET_MWC_TEXT_VALUE;
// GRIN wallet type
case Consensus.GRIN_WALLET_TYPE:
// Return GRIN wallet text value
return Consensus.WALLET_GRIN_TEXT_VALUE;
// EPIC wallet type
case Consensus.EPIC_WALLET_TYPE:
// Return EPIC wallet text value
return Consensus.WALLET_EPIC_TEXT_VALUE;
}
}
// Network type to text
static networkTypeToText(networkType) {
// Check network type
switch(networkType) {
// Mainnet network type
case Consensus.MAINNET_NETWORK_TYPE:
// Return mainnet network text value
return Consensus.NETWORK_MAINNET_TEXT_VALUE;
// Testnet network type
case Consensus.TESTNET_NETWORK_TYPE:
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC or EPIC wallet
case Consensus.MWC_WALLET_TYPE:
case Consensus.EPIC_WALLET_TYPE:
// Return floonet network text value
return Consensus.NETWORK_FLOONET_TEXT_VALUE;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return testnet network text value
return Consensus.NETWORK_TESTNET_TEXT_VALUE;
}
}
}
// Get reward
static getReward(isMainnet, fees, height) {
// Get block reward at height
var reward = Consensus.getBlockReward(isMainnet, height);
// Add fee to reward
reward = reward.plus(fees);
// Return reward
return reward;
}
// Is valid header version
static isValidHeaderVersion(isMainnet, height, version) {
// Return if version is valid at height while taking hard forks into account
return version.isEqualTo(Consensus.getHeaderVersion(isMainnet, height)) === true;
}
// Is no recent duplicate kernel enabled
static isNoRecentDuplicateKernelsEnabled(isMainnet) {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check if is mainnet
if(isMainnet === true) {
// Return false
return false;
}
// Otherwise
else {
// TODO Support no recent duplicate kernels
return false;
}
// Break
break;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Check if is mainnet
if(isMainnet === true) {
// Return false
return false;
}
// Otherwise
else {
// TODO Support no recent duplicate kernels
return false;
}
// Break
break;
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return false
return false;
}
}
// Block time seconds
static get BLOCK_TIME_SECONDS() {
// Return block time seconds
return 60;
}
// Block height minute
static get BLOCK_HEIGHT_MINUTE() {
// Return block height minute
return Math.floor(Common.SECONDS_IN_A_MINUTE / Consensus.BLOCK_TIME_SECONDS);
}
// Block height hour
static get BLOCK_HEIGHT_HOUR() {
// Return block height hour
return Common.MINUTES_IN_AN_HOUR * Consensus.BLOCK_HEIGHT_MINUTE;
}
// Block height day
static get BLOCK_HEIGHT_DAY() {
// Return block height day
return Common.HOURS_IN_A_DAY * Consensus.BLOCK_HEIGHT_HOUR;
}
// Block height week
static get BLOCK_HEIGHT_WEEK() {
// Return block height week
return Common.DAYS_IN_A_WEEK * Consensus.BLOCK_HEIGHT_DAY;
}
// Block height year
static get BLOCK_HEIGHT_YEAR() {
// Return block height year
return Common.WEEKS_IN_A_YEAR * Consensus.BLOCK_HEIGHT_WEEK;
}
// Coinbase maturity
static get COINBASE_MATURITY() {
// Return coinbase maturity
return Consensus.BLOCK_HEIGHT_DAY;
}
// First block height
static get FIRST_BLOCK_HEIGHT() {
// Return first block height
return 0;
}
// Value number base
static get VALUE_NUMBER_BASE() {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC or GRIN wallet
case Consensus.MWC_WALLET_TYPE:
case Consensus.GRIN_WALLET_TYPE:
// Return value number base
return 1E9;
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return value number base
return 1E8;
}
}
// Currency name
static get CURRENCY_NAME() {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Return currency name
return "MWC";
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return currency name
return "GRIN";
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return currency name
return "EPIC";
}
}
// Slatepack address human-readable part
static get SLATEPACK_ADDRESS_HUMAN_READABLE_PART() {
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network type
case Consensus.MAINNET_NETWORK_TYPE:
// Return Slatepack address human-readable part
return "grin";
// Testnet network type
case Consensus.TESTNET_NETWORK_TYPE:
// Return Slatepack address human-readable part
return "tgrin";
}
}
}
// MWC wallet type
static get MWC_WALLET_TYPE() {
// Return MWC wallet type
return 0;
}
// GRIN wallet type
static get GRIN_WALLET_TYPE() {
// Return GRIN wallet type
return Consensus.MWC_WALLET_TYPE + 1;
}
// EPIC wallet type
static get EPIC_WALLET_TYPE() {
// Return EPIC wallet type
return Consensus.GRIN_WALLET_TYPE + 1;
}
// Mainnet network type
static get MAINNET_NETWORK_TYPE() {
// Return mainnet network type
return 0;
}
// Testnet type
static get TESTNET_NETWORK_TYPE() {
// Return testnet network type
return Consensus.MAINNET_NETWORK_TYPE + 1;
}
// Legacy header version
static get LEGACY_HEADER_VERSION() {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC or GRIN wallet
case Consensus.MWC_WALLET_TYPE:
case Consensus.GRIN_WALLET_TYPE:
// Return legacy header version
return new BigNumber(1);
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return legacy header version
return new BigNumber(6);
}
}
// Block input weight
static get BLOCK_INPUT_WEIGHT() {
// Return block input weight
return 1;
}
// Block output weight
static get BLOCK_OUTPUT_WEIGHT() {
// Return block output weight
return 21;
}
// Block kernel weight
static get BLOCK_KERNEL_WEIGHT() {
// Return block kernel weight
return 3;
}
// Maximum block weight
static get MAXIMUM_BLOCK_WEIGHT() {
// Return maximum block weight
return 40000;
}
// BIP44 coin type
static get BIP44_COIN_TYPE() {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return BIP44 coin type
return 593;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return BIP44 coin type
return 1;
}
// Break
break;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return BIP44 coin type
return 592;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return BIP44 coin type
return 1;
}
// Break
break;
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return BIP44 coin type
return 23000;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return BIP44 coin type
return 1;
}
// Break
break;
}
}
// Explorer kernel excess URL
static get EXPLORER_KERNEL_EXCESS_URL() {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return explorer kernel excess URL
return "https://explorer.mwc.mw/#k";
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return explorer kernel excess URL
return "https://explorer.floonet.mwc.mw/#k";
}
// Break
break;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return no explorer URL
return Consensus.NO_EXPLORER_URL;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return no explorer URL
return Consensus.NO_EXPLORER_URL;
}
// Break
break;
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return no explorer URL
return Consensus.NO_EXPLORER_URL;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return no explorer URL
return Consensus.NO_EXPLORER_URL;
}
// Break
break;
}
}
// Explorer output commitment URL
static get EXPLORER_OUTPUT_COMMITMENT_URL() {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return explorer output commitment URL
return "https://explorer.mwc.mw/#o";
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return explorer output commitment URL
return "https://explorer.floonet.mwc.mw/#o";
}
// Break
break;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return no explorer URL
return Consensus.NO_EXPLORER_URL;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return no explorer URL
return Consensus.NO_EXPLORER_URL;
}
// Break
break;
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return explorer output commitment URL
return "https://explorer.epiccash.com/blockdetail/";
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return no explorer URL
return Consensus.NO_EXPLORER_URL;
}
// Break
break;
}
}
// No explorer URL
static get NO_EXPLORER_URL() {
// Return no explorer URL
return null;
}
// Hardware waller starting height
static get HARDWARE_WALLET_STARTING_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return hardware wallet starting height
return 1239928;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return hardware wallet starting height
return 1115028;
}
// Break
break;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return hardware wallet starting height
return 1687446;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return hardware wallet starting height
return 1195819;
}
// Break
break;
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Check network type
switch(Consensus.getNetworkType()) {
// Mainnet network
case Consensus.MAINNET_NETWORK_TYPE:
// Return hardware wallet starting height
return 1943415;
// Testnet network
case Consensus.TESTNET_NETWORK_TYPE:
// Return hardware wallet starting height
return 0;
}
// Break
break;
}
}
// Private
// Get block reward
static getBlockReward(isMainnet, height) {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check if height is the first block height
if(height.isEqualTo(Consensus.FIRST_BLOCK_HEIGHT) === true)
// Return genesis block reward
return new BigNumber("10000000041800000");
// Otherwise check if height is less than the second block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 2)) === true)
// Return reward during the first epoch range
return new BigNumber(2380952380);
// Otherwise check if height is less than the third block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 3)) === true)
// Return reward during the second epoch range
return new BigNumber(600000000);
// Otherwise check if height is less than the fourth block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 4)) === true)
// Return reward during the third epoch range
return new BigNumber(450000000);
// Otherwise check if height is less than the fifth block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 5)) === true)
// Return reward during the fourth epoch range
return new BigNumber(300000000);
// Otherwise check if height is less than the sixth block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 6)) === true)
// Return reward during the fifth epoch range
return new BigNumber(250000000);
// Otherwise check if height is less than the seventh block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 7)) === true)
// Return reward during the sixth epoch range
return new BigNumber(200000000);
// Otherwise check if height is less than the eighth block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 8)) === true)
// Return reward during the seventh epoch range
return new BigNumber(150000000);
// Otherwise check if height is less than the ninth block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 9)) === true)
// Return reward during the eighth epoch range
return new BigNumber(100000000);
// Otherwise check if height is less than the tenth block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 10)) === true)
// Return reward during the ninth epoch range
return new BigNumber(50000000);
// Otherwise check if height is less than the eleventh block offset
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 11)) === true)
// Return reward during the tenth epoch range
return new BigNumber(25000000);
// Otherwise check if height is less than the eleventh block offset plus the eleventh epoch duration
else if(height.isLessThan(Consensus.getEpochBlockOffset(isMainnet, 11).plus(Consensus.getEpochDuration(isMainnet, 11))) === true)
// Return reward during the eleventh epoch range
return new BigNumber(10000000);
// Otherwise check if height is equal to the eleventh block offset plus the eleventh epoch duration
else if(height.isEqualTo(Consensus.getEpochBlockOffset(isMainnet, 11).plus(Consensus.getEpochDuration(isMainnet, 11))) === true)
// Return reward during the twelfth epoch range
return new BigNumber(2211980);
// Otherwise
else
// Return zero
return new BigNumber(0);
// Break
break;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return block reward
return new BigNumber("60000000000");
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Check if is mainnet
if(isMainnet === true) {
// Check if height is the first block era
if(height.isLessThanOrEqualTo(Consensus.FIRST_BLOCK_ERA_HEIGHT) === true) {
// Return reward during the first block era
return new BigNumber("1600000000");
}
// Otherwise check if height is the second block era
else if(height.isLessThanOrEqualTo(Consensus.SECOND_BLOCK_ERA_HEIGHT) === true) {
// Return reward during the second block era
return new BigNumber("800000000");
}
// Otherwise check if height is the third block era
else if(height.isLessThanOrEqualTo(Consensus.THIRD_BLOCK_ERA_HEIGHT) === true) {
// Return reward during the third block era
return new BigNumber("400000000");
}
// Otherwise check if height is the fourth block era
else if(height.isLessThanOrEqualTo(Consensus.FOURTH_BLOCK_ERA_HEIGHT) === true) {
// Return reward during the fourth block era
return new BigNumber("200000000");
}
// Otherwise check if height is the fifth block era
else if(height.isLessThanOrEqualTo(Consensus.FIFTH_BLOCK_ERA_HEIGHT) === true) {
// Return reward during the fifth block era
return new BigNumber("100000000");
}
// Otherwise
else {
// Get height after fifth era
var heightAfterFifthEra = height.minus(Consensus.FIFTH_BLOCK_ERA_HEIGHT + 1);
// Return reward during current era
return (new BigNumber("15625000")).dividedToIntegerBy((new BigNumber(2)).exponentiatedBy(heightAfterFifthEra.dividedToIntegerBy(Consensus.SIXTH_AND_UP_BLOCK_ERA_INTERVAL)));
}
}
// Otherwise
else {
// Check if height is the first block era
if(height.isLessThanOrEqualTo(Consensus.FIRST_BLOCK_ERA_HEIGHT) === true) {
// Return reward during the first block era
return new BigNumber("1600000000");
}
// Otherwise
else {
// Return reward during the second block era
return new BigNumber("800000000");
}
}
// Break
break;
}
}
// Get epoch duration
static getEpochDuration(isMainnet, epoch) {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check epoch
switch(epoch) {
// One
case 1:
// Return duration of first epoch
return 0;
// Two
case 2:
// Return duration of second epoch
return (isMainnet === true) ? 120 * Consensus.BLOCK_HEIGHT_DAY : Consensus.BLOCK_HEIGHT_DAY;
// Three
case 3:
// Return duration of third epoch
return (isMainnet === true) ? 60 * Consensus.BLOCK_HEIGHT_DAY : Consensus.BLOCK_HEIGHT_DAY;
// Four
case 4:
// Return duration of fourth epoch
return 120 * Consensus.BLOCK_HEIGHT_DAY;
// Five
case 5:
// Return duration of fifth epoch
return 180 * Consensus.BLOCK_HEIGHT_DAY;
// Six
case 6:
// Return duration of sixth epoch
return 180 * Consensus.BLOCK_HEIGHT_DAY;
// Seven
case 7:
// Return duration of seventh epoch
return Consensus.BLOCK_HEIGHT_YEAR;
// Eight
case 8:
// Return duration of eighth epoch
return Consensus.BLOCK_HEIGHT_YEAR;
// Nine
case 9:
// Return duration of ninth epoch
return 6 * Consensus.BLOCK_HEIGHT_YEAR;
// Tenth
case 10:
// Return duration of tenth epoch
return 10 * Consensus.BLOCK_HEIGHT_YEAR;
// Eleven
case 11:
// Return duration of eleventh epoch
return 876349148;
}
}
}
// Get epoch block offset
static getEpochBlockOffset(isMainnet, epoch) {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Set offset to the C31 hard fork height
var offset = Consensus.getC31HardForkHeight(isMainnet);
// Check if past second epoch range
if(epoch >= 2)
// Add initial block duration to offset
offset = offset.plus((isMainnet === true) ? Consensus.BLOCK_HEIGHT_WEEK : Consensus.BLOCK_HEIGHT_DAY);
// Go through all remaining epoch ranges
for(var i = 3; i <= epoch; ++i)
// Add epoch's block duration to offset
offset = offset.plus(Consensus.getEpochDuration(isMainnet, i - 1));
// Return offset
return offset;
}
}
// Get C31 hard fork height
static getC31HardForkHeight(isMainnet) {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Return C31 hard fork height
return (isMainnet === true) ? new BigNumber(202500) : new BigNumber(270000);
}
}
// Get header version
static getHeaderVersion(isMainnet, height) {
// Check wallet type
switch(Consensus.getWalletType()) {
// MWC wallet
case Consensus.MWC_WALLET_TYPE:
// Check if height is less than the C31 hard fork height
if(height.isLessThan(Consensus.getC31HardForkHeight(isMainnet)) === true)
// Return legacy header version
return Consensus.LEGACY_HEADER_VERSION;
// Otherwise
else
// Return second header version
return Consensus.LEGACY_HEADER_VERSION.plus(1);
// Break
break;
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Check if mainnet
if(isMainnet === true) {
// Get header version based on number of hard forks
var headerVersion = height.dividedToIntegerBy(Consensus.HARD_FORK_INTERVAL).plus(1);
// Check if header version is greater than the maximum header version
if(headerVersion.isGreaterThan(Consensus.MAXIMUM_HEADER_VERSION) === true)
// Set header version to the maximum header version
headerVersion = new BigNumber(Consensus.MAXIMUM_HEADER_VERSION);
// Return header version
return headerVersion;
}
// Otherwise
else {
// Check is height is less than first hard fork height
if(height.isLessThan(Consensus.FIRST_HARD_FORK_HEIGHT) === true)
// Return legacy header version
return Consensus.LEGACY_HEADER_VERSION;
// Otherwise check if height is less than second hard fork height
else if(height.isLessThan(Consensus.SECOND_HARD_FORK_HEIGHT) === true)
// Return second header version
return Consensus.LEGACY_HEADER_VERSION.plus(1);
// Otherwise check if height is less than third hard fork height
else if(height.isLessThan(Consensus.THIRD_HARD_FORK_HEIGHT) === true)
// Return third header version
return Consensus.LEGACY_HEADER_VERSION.plus(2);
// Otherwise check if height is less than fourth hard forks height
else if(height.isLessThan(Consensus.FOURTH_HARD_FORK_HEIGHT) === true)
// Return fourth header version
return Consensus.LEGACY_HEADER_VERSION.plus(3);
// Otherwise
else
// Return fifth header version
return Consensus.LEGACY_HEADER_VERSION.plus(4);
}
// Break
break;
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Check if height is less than the first hard fork height
if(height.isLessThan(Consensus.getFirstHardForkHeight(isMainnet)) === true)
// Return legacy header version
return Consensus.LEGACY_HEADER_VERSION;
// Otherwise
else
// Return second header version
return Consensus.LEGACY_HEADER_VERSION.plus(1);
// Break
break;
}
}
// Get first hard fork height
static getFirstHardForkHeight(isMainnet) {
// Check wallet type
switch(Consensus.getWalletType()) {
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return first hard fork height
return (isMainnet === true) ? new BigNumber(9000000) : new BigNumber(25800);
}
}
// Hard fork interval
static get HARD_FORK_INTERVAL() {
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return hard fork interval
return Math.floor(Consensus.BLOCK_HEIGHT_YEAR / 2);
}
}
// First hard fork height
static get FIRST_HARD_FORK_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return first hard fork height
return 185040;
}
}
// Second hard fork height
static get SECOND_HARD_FORK_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return second hard fork height
return 298080;
}
}
// Third hard fork height
static get THIRD_HARD_FORK_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return third hard fork height
return 552960;
}
}
// Fourth hard fork height
static get FOURTH_HARD_FORK_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return fourth hard fork height
return 642240;
}
}
// Maximum header version
static get MAXIMUM_HEADER_VERSION() {
// Check wallet type
switch(Consensus.getWalletType()) {
// GRIN wallet
case Consensus.GRIN_WALLET_TYPE:
// Return maximum header version
return 5;
}
}
// Default Wallet type
static get DEFAULT_WALLET_TYPE() {
// Return default wallet type
return Consensus.MWC_WALLET_TYPE;
}
// Default network type
static get DEFAULT_NETWORK_TYPE() {
// Return default network type
return Consensus.MAINNET_NETWORK_TYPE;
}
// Wallet MWC text value
static get WALLET_MWC_TEXT_VALUE() {
// Return wallet MWC text value
return (typeof Language !== "undefined") ? Language.getDefaultTranslation('MimbleWimble Coin') : "MimbleWimble Coin";
}
// Wallet GRIN value
static get WALLET_GRIN_TEXT_VALUE() {
// Return wallet GRIN text value
return (typeof Language !== "undefined") ? Language.getDefaultTranslation('Grin') : "Grin";
}
// Wallet EPIC value
static get WALLET_EPIC_TEXT_VALUE() {
// Return wallet EPIC text value
return (typeof Language !== "undefined") ? Language.getDefaultTranslation('Epic Cash') : "Epic Cash";
}
// Network mainnet value
static get NETWORK_MAINNET_TEXT_VALUE() {
// Return network mainnet text value
return (typeof Language !== "undefined") ? Language.getDefaultTranslation('Mainnet') : "Mainnet";
}
// Network floonet value
static get NETWORK_FLOONET_TEXT_VALUE() {
// Return network floonet text value
return (typeof Language !== "undefined") ? Language.getDefaultTranslation('Floonet') : "Floonet";
}
// Network testnet value
static get NETWORK_TESTNET_TEXT_VALUE() {
// Return network testnet text value
return (typeof Language !== "undefined") ? Language.getDefaultTranslation('Testnet') : "Testnet";
}
// Override wallet type URL parameter name
static get OVERRIDE_WALLET_TYPE_URL_PARAMETER_NAME() {
// Return override wallet type URL parameter name
return "Override Wallet Type";
}
// Override network type URL parameter name
static get OVERRIDE_NETWORK_TYPE_URL_PARAMETER_NAME() {
// Return override network type URL parameter name
return "Override Network Type";
}
// First block era height
static get FIRST_BLOCK_ERA_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return first block era height
return 334 * Consensus.BLOCK_HEIGHT_DAY;
}
}
// Second block era height
static get SECOND_BLOCK_ERA_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return second block era height
return 470 * Consensus.BLOCK_HEIGHT_DAY + Consensus.FIRST_BLOCK_ERA_HEIGHT;
}
}
// Third block era height
static get THIRD_BLOCK_ERA_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return third block era height
return 601 * Consensus.BLOCK_HEIGHT_DAY + Consensus.SECOND_BLOCK_ERA_HEIGHT;
}
}
// Fourth block era height
static get FOURTH_BLOCK_ERA_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return fourth block era height
return 800 * Consensus.BLOCK_HEIGHT_DAY + Consensus.THIRD_BLOCK_ERA_HEIGHT;
}
}
// Fifth block era height
static get FIFTH_BLOCK_ERA_HEIGHT() {
// Check wallet type
switch(Consensus.getWalletType()) {
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return fifth block era height
return 1019 * Consensus.BLOCK_HEIGHT_DAY + Consensus.FOURTH_BLOCK_ERA_HEIGHT;
}
}
// Sixth and up block era interval
static get SIXTH_AND_UP_BLOCK_ERA_INTERVAL() {
// Check wallet type
switch(Consensus.getWalletType()) {
// EPIC wallet
case Consensus.EPIC_WALLET_TYPE:
// Return sixth and up block era interval
return 1460 * Consensus.BLOCK_HEIGHT_DAY;
}
}
// Wallet type local storage name
static get WALLET_TYPE_LOCAL_STORAGE_NAME() {
// Return wallet type local storage name
return "Wallet Type";
}
// Network type local storage name
static get NETWORK_TYPE_LOCAL_STORAGE_NAME() {
// Return network type local storage name
return "Network Type";
}
}
// Main function
// Set global object's consensus
globalThis["Consensus"] = Consensus;
// Check if not not a web worker
if(typeof self === "undefined" || typeof WorkerGlobalScope === "undefined" || self instanceof WorkerGlobalScope === false) {
// Initialize consensus
Consensus.initialize();
}