Skip to content

Commit

Permalink
Added box plots for distances and scores, added additional distance/s…
Browse files Browse the repository at this point in the history
…core functions for testing purposes
  • Loading branch information
u-hubar committed Jan 22, 2024
1 parent cb4db12 commit 4133c35
Show file tree
Hide file tree
Showing 4 changed files with 343 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,4 @@ data*
.vscode/launch.json

# KAs Distribution Simulation Script Plots
tools/knowledge-assets-distribution-simulation/plots/*jpg
tools/knowledge-assets-distribution-simulation/plots/**/*jpg
156 changes: 145 additions & 11 deletions src/service/proximity-scoring-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ class ProximityScoringService {
this.proximityScoreFunctionsPairs = {
1: [this.calculateBinaryXOR.bind(this), this.Log2PLDSF.bind(this)],
2: [this.calculateProximityOnHashRing.bind(this), this.LinearLogisticSum.bind(this)],
3: [this.calculateProximityOnHashRing.bind(this), this.LinearSum.bind(this)],
4: [this.calculateProximityOnHashRing.bind(this), this.LinearDivision.bind(this)],
5: [
this.calculateProximityOnHashRing.bind(this),
this.LinearEMANormalization.bind(this),
],
6: [this.calculateRelativeDistance.bind(this), this.RelativeNormalization.bind(this)],
};
}

Expand Down Expand Up @@ -62,17 +69,55 @@ class ProximityScoringService {
keyHash,
);

let directDistance = peerPositionOnHashRing.sub(keyPositionOnHashRing);

if (directDistance.lt(0)) {
directDistance = directDistance.add(HASH_RING_SIZE);
}

const directDistance = peerPositionOnHashRing.gt(keyPositionOnHashRing)
? peerPositionOnHashRing.sub(keyPositionOnHashRing)
: keyPositionOnHashRing.sub(peerPositionOnHashRing);
const wraparoundDistance = HASH_RING_SIZE.sub(directDistance);

return directDistance.lt(wraparoundDistance) ? directDistance : wraparoundDistance;
}

async calculateRelativeDistance(blockchain, peerHash, keyHash, nodes) {
const peerHashBN = await this.blockchainModuleManager.toBigNumber(blockchain, peerHash);
const keyHashBN = await this.blockchainModuleManager.toBigNumber(blockchain, keyHash);

const positions = await Promise.all(
nodes.map(async (node) =>
this.blockchainModuleManager.toBigNumber(blockchain, node.sha256),
),
);

const closestNode = positions.reduce((prev, curr) => {
const diffCurr = curr.sub(keyHashBN).abs();
const diffPrev = prev.sub(keyHashBN).abs();

return diffCurr.lt(diffPrev) ? curr : prev;
});

const sortedPositions = positions.sort((a, b) => a.sub(b));

const closestNodeIndex = sortedPositions.findIndex((pos) => pos.eq(closestNode));
const peerIndex = sortedPositions.findIndex((pos) => pos.eq(peerHashBN));

return this.blockchainModuleManager.toBigNumber(
blockchain,
Math.abs(peerIndex - closestNodeIndex),
);
}

async RelativeNormalization(blockchain, distance, stake) {
const w1 = 3;
const w2 = 1;

const mappedDistance = distance / 10;
const proximityScore = 1 - mappedDistance;
const mappedStake = (stake - 50000) / (1000000 - 50000);

const score = w1 * proximityScore + w2 * mappedStake;

return { mappedDistance, mappedStake, score };
}

async Log2PLDSF(blockchain, distance, stake) {
const log2PLDSFParams = await this.blockchainModuleManager.getLog2PLDSFParams(blockchain);

Expand All @@ -98,10 +143,16 @@ class ProximityScoringService {
const dividend = mappedStake.pow(stakeExponent).mul(a).add(b);
const divisor = mappedDistance.pow(distanceExponent).mul(c).add(d);

return Math.floor(
Number(multiplier) *
Math.log2(Number(logArgumentConstant) + dividend.toNumber() / divisor.toNumber()),
);
return {
mappedDistance,
mappedStake,
score: Math.floor(
Number(multiplier) *
Math.log2(
Number(logArgumentConstant) + dividend.toNumber() / divisor.toNumber(),
),
),
};
}

// Using Maclaurin Series to approximate e^x
Expand Down Expand Up @@ -142,7 +193,90 @@ class ProximityScoringService {
const proximityScore = w1 * (1 - mappedDistance);
const stakeScore = w2 * mappedStake;

return proximityScore + stakeScore;
return { mappedDistance, mappedStake, score: proximityScore + stakeScore };
}

async LinearSum(blockchain, distance, stake) {
const linearSumParams = await this.blockchainModuleManager.getLinearSumParams(blockchain);
const { distanceScaleFactor, w1, w2 } = linearSumParams;

let dividend = distance;
let divisor = HASH_RING_SIZE.div(2);
if (dividend.gt(UINT128_MAX_BN) || divisor.gt(UINT128_MAX_BN)) {
dividend = dividend.div(distanceScaleFactor);
divisor = divisor.div(distanceScaleFactor);
}

const divResult = dividend.mul(distanceScaleFactor).div(divisor);
const mappedDistance =
parseFloat(divResult.toString()) / parseFloat(distanceScaleFactor.toString());

const maxStake = await this.blockchainModuleManager.getMaximumStake(blockchain);
const mappedStake =
stake / Number(await this.blockchainModuleManager.convertFromWei(maxStake));

const proximityScore = w1 * (1 - mappedDistance);
const stakeScore = w2 * mappedStake;

return { mappedDistance, mappedStake, score: proximityScore + stakeScore };
}

async LinearDivision(blockchain, distance, stake) {
const linearDivisionParams = await this.blockchainModuleManager.getLinearDivisionParams(
blockchain,
);
const { distanceScaleFactor, w1, w2 } = linearDivisionParams;

let dividend = distance;
let divisor = HASH_RING_SIZE.div(2);
if (dividend.gt(UINT128_MAX_BN) || divisor.gt(UINT128_MAX_BN)) {
dividend = dividend.div(distanceScaleFactor);
divisor = divisor.div(distanceScaleFactor);
}

const divResult = dividend.mul(distanceScaleFactor).div(divisor);
const mappedDistance =
parseFloat(divResult.toString()) / parseFloat(distanceScaleFactor.toString());

const maxStake = await this.blockchainModuleManager.getMaximumStake(blockchain);
const mappedStake =
Math.log(stake + 1) /
Math.log(1 + Number(await this.blockchainModuleManager.convertFromWei(maxStake)));

const proximityScore = w1 * (1 - mappedDistance);
const stakeScore = w2 * mappedStake;

return { mappedDistance, mappedStake, score: stakeScore / proximityScore };
}

async LinearEMANormalization(blockchain, distance, stake, nodeDistanceEMA) {
// const linearEMANormalizationParams = await this.blockchainModuleManager.getLinearEMANormalizationParams(blockchain);
// const { w1, w2 } = linearEMANormalizationParams;

const w1 = 2;
const w2 = 1;

const distanceScaleFactor = '1000000000000000000';

let dividend = distance;
let divisor = nodeDistanceEMA;
if (dividend.gt(UINT128_MAX_BN) || divisor.gt(UINT128_MAX_BN)) {
dividend = dividend.div(distanceScaleFactor);
divisor = divisor.div(distanceScaleFactor);
}

const divResult = dividend.mul(distanceScaleFactor).div(divisor);
const mappedDistance =
parseFloat(divResult.toString()) / parseFloat(distanceScaleFactor.toString());

const maxStake = await this.blockchainModuleManager.getMaximumStake(blockchain);
const mappedStake =
stake / Number(await this.blockchainModuleManager.convertFromWei(maxStake));

const proximityScore = w1 * (1 - mappedDistance);
const stakeScore = w2 * mappedStake;

return { mappedDistance, mappedStake, score: proximityScore + stakeScore };
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ class BlockchainModuleManagerMock {
return ethers.utils.hexlify(uint8Array);
}

convertFromWei(value, toUnit = 'ether') {
return ethers.utils.formatUnits(value, toUnit);
}

convertToWei(blockchain, value, fromUnit = 'ether') {
return ethers.utils.parseUnits(value.toString(), fromUnit).toString();
}
Expand All @@ -17,6 +21,10 @@ class BlockchainModuleManagerMock {
return ethers.BigNumber.from(value);
}

getMaximumStake(blockchain) {
return '1000000000000000000000000';
}

getLog2PLDSFParams(blockchain) {
return {
distanceMappingCoefficient:
Expand All @@ -43,6 +51,14 @@ class BlockchainModuleManagerMock {
w2: 1,
};
}

getLinearSumParams(blockchain) {
return { distanceScaleFactor: '1000000000000000000', w1: 1, w2: 0.25 };
}

getLinearDivisionParams(blockchain) {
return { distanceScaleFactor: '1000000000000000000', w1: 1, w2: 0.1 };
}
}

export default BlockchainModuleManagerMock;
Loading

0 comments on commit 4133c35

Please sign in to comment.