Skip to content

Commit

Permalink
fix: update new helper
Browse files Browse the repository at this point in the history
  • Loading branch information
thanhnv2303 committed Nov 2, 2022
1 parent 0b45788 commit 68617e4
Show file tree
Hide file tree
Showing 7 changed files with 315 additions and 20 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tovchain/cosms",
"version": "0.7.2",
"version": "0.7.6",
"description": "query data form cosmos base networks template",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
Expand Down Expand Up @@ -48,7 +48,8 @@
"@cosmjs/proto-signing": "^0.29.0",
"@cosmjs/stargate": "^0.29.0",
"cosmjs-types": "^0.5.1",
"crypto-addr-codec": "^0.1.7"
"crypto-addr-codec": "^0.1.7",
"deepmerge": "^4.2.2"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
Expand Down
10 changes: 10 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
import Cosm from './lib/cosm';

export { BatchHttpClient } from './lib/tendermint-batch-rpc/batchhttpclient';
export { BatchRpcClient } from './lib/tendermint-batch-rpc/batchrpcclient';
export {
TendermintBatchClient
} from './lib/tendermint-batch-rpc/tendermintbatchclient';

export { BaseProvider } from './lib/providers';
export { Wallet } from './lib/wallet';

export default Cosm;
16 changes: 10 additions & 6 deletions src/lib/cosm/test_helper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { BaseProvider } from '../providers';

import Cosm from './index';

const rpcUrl = 'https://testnet.rpc.orai.io';
// const rpcUrl = "https://public-rpc1.stafihub.io";
// const rpcUrl = "https://rpc-cosmoshub.keplr.app";
// const rpcUrl = 'https://testnet.rpc.orai.io';
const rpcUrl = 'https://rpc.orai.io';
// const rpcUrl = 'https://public-rpc1.stafihub.io';
// const rpcUrl = "https://node1.konstellation.tech:26657";
// const rpcUrl = "https://konstellation-rpc.polkachu.com";
// const rpcUrl = "https://rpc-archive.sifchain.finance";
// const rpcUrl = "https://rpc-sifchain.ecostake.com";
// const rpcUrl = "https://rpc-osmosis.keplr.app";
// const rpcUrl = 'https://osmosis-testnet-rpc.allthatnode.com:26657';
let provider;
Expand All @@ -22,10 +26,10 @@ describe('Cosm test', async () => {
describe('Test message', async () => {
it('Test helper', async function() {

const start = 8568000;
const end = 8568202;
const end = await provider.batchQueryClient.getHeight();
const start = end - 100;

let uptime = await cosm.helper.getUptime(start, end);
let uptime = await cosm.helper.getUptimeBatch(start, end,40);
console.log(uptime);
});
});
Expand Down
47 changes: 42 additions & 5 deletions src/lib/helpers/index.js.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as responses
from '@cosmjs/tendermint-rpc/build/tendermint35/responses';
import deepmerge from 'deepmerge';
import Cosm from '../cosm';
import { breakToRanges, mergeWithAdd } from '../utils/range';

export class Helper {
private cosm: Cosm;
Expand All @@ -9,7 +11,7 @@ export class Helper {
this.cosm = cosm;
}

async getBatchBlock(startBlock, endBlock) {
async getBlocks(startBlock, endBlock) {
const tendermint = this.cosm.tendermint;
for (let i = startBlock; i < endBlock + 1; i++) {
await tendermint.block(i);
Expand All @@ -24,8 +26,18 @@ export class Helper {
return blockResults;
}

async getBatchBlock(startBlock, endBlock, batchSize = 1000) {
const ranges = breakToRanges(startBlock, endBlock, batchSize);
let blockResults = {};
for (const range of ranges) {
let blocks = await this.getBlocks(range[0], range[1]);
blockResults = { ...blockResults, ...blocks };
}
return blockResults;
}

async getUptime(startBlock, endBlock) {
let blocks = await this.getBatchBlock(startBlock, endBlock);
let blocks = await this.getBlocks(startBlock, endBlock);
let upTimeResult = {};
let proposeTimeResult = {};

Expand All @@ -36,9 +48,14 @@ export class Helper {
proposeTimeResult[proposerAddress] = proposeTime + 1;
let signatures = block.block.lastCommit.signatures;
for (const signature of signatures) {
let validatorAddress = Cosm.utils.uint8Array.toHex(signature.validatorAddress);
let upTime = upTimeResult[validatorAddress] | 0;
upTimeResult[validatorAddress] = upTime + 1;
try {
let validatorAddress = Cosm.utils.uint8Array.toHex(signature.validatorAddress);
let upTime = upTimeResult[validatorAddress] | 0;
upTimeResult[validatorAddress] = upTime + 1;
} catch (e) {
console.debug(`Warn: block.lastCommit.signatures : signature ${JSON.stringify(signature)}`);
}

}
}
return {
Expand All @@ -48,4 +65,24 @@ export class Helper {
proposeTime: proposeTimeResult
};
}

async getUptimeBatch(startBlock, endBlock, batchSize = 1000) {
let ranges = breakToRanges(startBlock, endBlock, batchSize);
let upTimeResults = {
startBlock: startBlock,
endBlock: endBlock,
upTime: {},
proposeTime: {}
};


for (const range of ranges) {
const upTime = await this.getUptime(range[0], range[1]);
upTimeResults.upTime = deepmerge(upTime.upTime,upTimeResults.upTime);
upTimeResults.proposeTime = deepmerge(upTime.proposeTime,upTimeResults.proposeTime);

}
return upTimeResults;
}
}

208 changes: 208 additions & 0 deletions src/lib/utils/bech32.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
'use strict';
const ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';

const ALPHABET_MAP: { [key: string]: number } = {};
for (let z = 0; z < ALPHABET.length; z++) {
const x = ALPHABET.charAt(z);
ALPHABET_MAP[x] = z;
}

function polymodStep(pre: number): number {
const b = pre >> 25;
return (
((pre & 0x1ffffff) << 5) ^
(-((b >> 0) & 1) & 0x3b6a57b2) ^
(-((b >> 1) & 1) & 0x26508e6d) ^
(-((b >> 2) & 1) & 0x1ea119fa) ^
(-((b >> 3) & 1) & 0x3d4233dd) ^
(-((b >> 4) & 1) & 0x2a1462b3)
);
}

function prefixChk(prefix: string): number | string {
let chk = 1;
for (let i = 0; i < prefix.length; ++i) {
const c = prefix.charCodeAt(i);
if (c < 33 || c > 126) return 'Invalid prefix (' + prefix + ')';

chk = polymodStep(chk) ^ (c >> 5);
}
chk = polymodStep(chk);

for (let i = 0; i < prefix.length; ++i) {
const v = prefix.charCodeAt(i);
chk = polymodStep(chk) ^ (v & 0x1f);
}
return chk;
}

function convert(data: ArrayLike<number>, inBits: number, outBits: number, pad: true): number[];
function convert(
data: ArrayLike<number>,
inBits: number,
outBits: number,
pad: false,
): number[] | string;
function convert(
data: ArrayLike<number>,
inBits: number,
outBits: number,
pad: boolean,
): number[] | string {
let value = 0;
let bits = 0;
const maxV = (1 << outBits) - 1;

const result: number[] = [];
for (let i = 0; i < data.length; ++i) {
value = (value << inBits) | data[i];
bits += inBits;

while (bits >= outBits) {
bits -= outBits;
result.push((value >> bits) & maxV);
}
}

if (pad) {
if (bits > 0) {
result.push((value << (outBits - bits)) & maxV);
}
} else {
if (bits >= inBits) return 'Excess padding';
if ((value << (outBits - bits)) & maxV) return 'Non-zero padding';
}

return result;
}

function toWords(bytes: ArrayLike<number>): number[] {
return convert(bytes, 8, 5, true);
}

function fromWordsUnsafe(words: ArrayLike<number>): number[] | undefined {
const res = convert(words, 5, 8, false);
if (Array.isArray(res)) return res;
}

function fromWords(words: ArrayLike<number>): number[] {
const res = convert(words, 5, 8, false);
if (Array.isArray(res)) return res;

throw new Error(res);
}

function getLibraryFromEncoding(encoding: 'bech32' | 'bech32m'): BechLib {
let ENCODING_CONST: number;
if (encoding === 'bech32') {
ENCODING_CONST = 1;
} else {
ENCODING_CONST = 0x2bc830a3;
}

function encode(prefix: string, words: ArrayLike<number>, LIMIT?: number): string {
LIMIT = LIMIT || 90;
if (prefix.length + 7 + words.length > LIMIT) throw new TypeError('Exceeds length limit');

prefix = prefix.toLowerCase();

// determine chk mod
let chk = prefixChk(prefix);
if (typeof chk === 'string') throw new Error(chk);

let result = prefix + '1';
for (let i = 0; i < words.length; ++i) {
const x = words[i];
if (x >> 5 !== 0) throw new Error('Non 5-bit word');

chk = polymodStep(chk) ^ x;
result += ALPHABET.charAt(x);
}

for (let i = 0; i < 6; ++i) {
chk = polymodStep(chk);
}
chk ^= ENCODING_CONST;

for (let i = 0; i < 6; ++i) {
const v = (chk >> ((5 - i) * 5)) & 0x1f;
result += ALPHABET.charAt(v);
}

return result;
}

function __decode(str: string, LIMIT?: number): Decoded | string {
LIMIT = LIMIT || 90;
if (str.length < 8) return str + ' too short';
if (str.length > LIMIT) return 'Exceeds length limit';

// don't allow mixed case
const lowered = str.toLowerCase();
const uppered = str.toUpperCase();
if (str !== lowered && str !== uppered) return 'Mixed-case string ' + str;
str = lowered;

const split = str.lastIndexOf('1');
if (split === -1) return 'No separator character for ' + str;
if (split === 0) return 'Missing prefix for ' + str;

const prefix = str.slice(0, split);
const wordChars = str.slice(split + 1);
if (wordChars.length < 6) return 'Data too short';

let chk = prefixChk(prefix);
if (typeof chk === 'string') return chk;

const words = [];
for (let i = 0; i < wordChars.length; ++i) {
const c = wordChars.charAt(i);
const v = ALPHABET_MAP[c];
if (v === undefined) return 'Unknown character ' + c;
chk = polymodStep(chk) ^ v;

// not in the checksum?
if (i + 6 >= wordChars.length) continue;
words.push(v);
}

if (chk !== ENCODING_CONST) return 'Invalid checksum for ' + str;
return { prefix, words };
}

function decodeUnsafe(str: string, LIMIT?: number): Decoded | undefined {
const res = __decode(str, LIMIT);
if (typeof res === 'object') return res;
}

function decode(str: string, LIMIT?: number): Decoded {
const res = __decode(str, LIMIT);
if (typeof res === 'object') return res;

throw new Error(res);
}

return {
decodeUnsafe,
decode,
encode,
toWords,
fromWordsUnsafe,
fromWords,
};
}

export const bech32 = getLibraryFromEncoding('bech32');
export const bech32m = getLibraryFromEncoding('bech32m');
export interface Decoded {
prefix: string;
words: number[];
}
export interface BechLib {
decodeUnsafe: (str: string, LIMIT?: number | undefined) => Decoded | undefined;
decode: (str: string, LIMIT?: number | undefined) => Decoded;
encode: (prefix: string, words: ArrayLike<number>, LIMIT?: number | undefined) => string;
toWords: typeof toWords;
fromWordsUnsafe: typeof fromWordsUnsafe;
fromWords: typeof fromWords;
}
Loading

0 comments on commit 68617e4

Please sign in to comment.