mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
fix: block results validator update decoder (#1162)
* fix: block results validator update decoder * Test decofing results Co-authored-by: blorgon1 <102304575+blorgon1@users.noreply.github.com>
This commit is contained in:
commit
79473bb308
@ -18,6 +18,12 @@ and this project adheres to
|
||||
- @cosmjs/stargate: Let `calculateFee` handle fee amounts that exceed the safe
|
||||
integer range.
|
||||
|
||||
### Fixed
|
||||
|
||||
- @cosmjs/tendermint-rpc: Fix block results validator update decoder. ([#1151])
|
||||
|
||||
[#1151]: https://github.com/cosmos/cosmjs/issues/1151
|
||||
|
||||
## [0.28.4] - 2022-04-15
|
||||
|
||||
### Added
|
||||
|
@ -0,0 +1,77 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { fromBase64, fromHex } from "@cosmjs/encoding";
|
||||
|
||||
import { decodeValidatorGenesis, decodeValidatorInfo, decodeValidatorUpdate } from "./responses";
|
||||
|
||||
describe("Adaptor Responses", () => {
|
||||
describe("decodeValidatorGenesis", () => {
|
||||
it("works for genesis format", () => {
|
||||
// from https://raw.githubusercontent.com/cosmos/mainnet/master/genesis.json
|
||||
const validator = decodeValidatorGenesis({
|
||||
address: "A03DC128D38DB0BC5F18AE1872F1CB2E1FD41157",
|
||||
name: "真本聪&IOSG",
|
||||
power: "169980",
|
||||
pub_key: {
|
||||
type: "tendermint/PubKeyEd25519",
|
||||
value: "2BX6Zuj8RmdJAkD1BAg6KB0v04liyM7jBdwOGIb9F9Q=",
|
||||
},
|
||||
});
|
||||
expect(validator).toEqual({
|
||||
address: fromHex("A03DC128D38DB0BC5F18AE1872F1CB2E1FD41157"),
|
||||
votingPower: 169980,
|
||||
pubkey: {
|
||||
algorithm: "ed25519",
|
||||
data: fromBase64("2BX6Zuj8RmdJAkD1BAg6KB0v04liyM7jBdwOGIb9F9Q="),
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("decodeValidatorUpdate", () => {
|
||||
it("works for block results format", () => {
|
||||
// from https://rpc.cosmos.network/block_results?height=10539773
|
||||
const update = decodeValidatorUpdate({
|
||||
pub_key: {
|
||||
Sum: {
|
||||
type: "tendermint.crypto.PublicKey_Ed25519",
|
||||
value: {
|
||||
ed25519: "0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI=",
|
||||
},
|
||||
},
|
||||
},
|
||||
power: "11418237",
|
||||
});
|
||||
expect(update).toEqual({
|
||||
pubkey: {
|
||||
algorithm: "ed25519",
|
||||
data: fromBase64("0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI="),
|
||||
},
|
||||
votingPower: 11418237,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("decodeValidatorInfo", () => {
|
||||
it("works for validators format", () => {
|
||||
// from https://rpc.cosmos.network/validators?height=10601034
|
||||
const info = decodeValidatorInfo({
|
||||
address: "AC2D56057CD84765E6FBE318979093E8E44AA18F",
|
||||
pub_key: {
|
||||
type: "tendermint/PubKeyEd25519",
|
||||
value: "0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI=",
|
||||
},
|
||||
voting_power: "11228980",
|
||||
proposer_priority: "62870960",
|
||||
});
|
||||
expect(info).toEqual({
|
||||
address: fromHex("AC2D56057CD84765E6FBE318979093E8E44AA18F"),
|
||||
pubkey: {
|
||||
algorithm: "ed25519",
|
||||
data: fromBase64("0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI="),
|
||||
},
|
||||
votingPower: 11228980,
|
||||
proposerPriority: 62870960,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -148,49 +148,51 @@ function decodeTxData(data: RpcTxData): responses.TxData {
|
||||
};
|
||||
}
|
||||
|
||||
// yes, a different format for status and dump consensus state
|
||||
interface RpcPubkey {
|
||||
readonly type: string;
|
||||
/** base64 encoded */
|
||||
readonly value: string;
|
||||
}
|
||||
type RpcPubkey =
|
||||
| {
|
||||
readonly type: string;
|
||||
/** base64 encoded */
|
||||
readonly value: string;
|
||||
}
|
||||
| {
|
||||
// See: https://github.com/cosmos/cosmjs/issues/1142
|
||||
readonly Sum: {
|
||||
readonly type: string;
|
||||
readonly value: {
|
||||
/** base64 encoded */
|
||||
[algorithm: string]: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
function decodePubkey(data: RpcPubkey): ValidatorPubkey {
|
||||
switch (data.type) {
|
||||
// go-amino special code
|
||||
case "tendermint/PubKeyEd25519":
|
||||
return {
|
||||
algorithm: "ed25519",
|
||||
data: fromBase64(assertNotEmpty(data.value)),
|
||||
};
|
||||
case "tendermint/PubKeySecp256k1":
|
||||
return {
|
||||
algorithm: "secp256k1",
|
||||
data: fromBase64(assertNotEmpty(data.value)),
|
||||
};
|
||||
default:
|
||||
throw new Error(`unknown pubkey type: ${data.type}`);
|
||||
if ("Sum" in data) {
|
||||
// we don't need to check type because we're checking algorithm
|
||||
const [[algorithm, value]] = Object.entries(data.Sum.value);
|
||||
assert(algorithm === "ed25519" || algorithm === "secp256k1", `unknown pubkey type: ${algorithm}`);
|
||||
return {
|
||||
algorithm,
|
||||
data: fromBase64(assertNotEmpty(value)),
|
||||
};
|
||||
} else {
|
||||
switch (data.type) {
|
||||
// go-amino special code
|
||||
case "tendermint/PubKeyEd25519":
|
||||
return {
|
||||
algorithm: "ed25519",
|
||||
data: fromBase64(assertNotEmpty(data.value)),
|
||||
};
|
||||
case "tendermint/PubKeySecp256k1":
|
||||
return {
|
||||
algorithm: "secp256k1",
|
||||
data: fromBase64(assertNotEmpty(data.value)),
|
||||
};
|
||||
default:
|
||||
throw new Error(`unknown pubkey type: ${data.type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for evidence, block results, etc.
|
||||
interface RpcValidatorUpdate {
|
||||
/** hex encoded */
|
||||
readonly address: string;
|
||||
readonly pub_key: RpcPubkey;
|
||||
readonly voting_power: string;
|
||||
readonly proposer_priority: string;
|
||||
}
|
||||
|
||||
function decodeValidatorUpdate(data: RpcValidatorUpdate): responses.Validator {
|
||||
return {
|
||||
pubkey: decodePubkey(assertObject(data.pub_key)),
|
||||
votingPower: Integer.parse(assertNotEmpty(data.voting_power)),
|
||||
address: fromHex(assertNotEmpty(data.address)),
|
||||
proposerPriority: Integer.parse(data.proposer_priority),
|
||||
};
|
||||
}
|
||||
|
||||
interface RpcBlockParams {
|
||||
readonly max_bytes: string;
|
||||
readonly max_gas: string;
|
||||
@ -252,6 +254,19 @@ function decodeConsensusParams(data: RpcConsensusParams): responses.ConsensusPar
|
||||
};
|
||||
}
|
||||
|
||||
// for block results
|
||||
interface RpcValidatorUpdate {
|
||||
readonly pub_key: RpcPubkey;
|
||||
readonly power: string;
|
||||
}
|
||||
|
||||
export function decodeValidatorUpdate(data: RpcValidatorUpdate): responses.ValidatorUpdate {
|
||||
return {
|
||||
pubkey: decodePubkey(assertObject(data.pub_key)),
|
||||
votingPower: Integer.parse(assertNotEmpty(data.power)),
|
||||
};
|
||||
}
|
||||
|
||||
interface RpcBlockResultsResponse {
|
||||
readonly height: string;
|
||||
readonly txs_results: readonly RpcTxData[] | null;
|
||||
@ -493,7 +508,7 @@ interface RpcValidatorGenesis {
|
||||
readonly name?: string;
|
||||
}
|
||||
|
||||
function decodeValidatorGenesis(data: RpcValidatorGenesis): responses.Validator {
|
||||
export function decodeValidatorGenesis(data: RpcValidatorGenesis): responses.Validator {
|
||||
return {
|
||||
address: fromHex(assertNotEmpty(data.address)),
|
||||
pubkey: decodePubkey(assertObject(data.pub_key)),
|
||||
@ -534,13 +549,15 @@ interface RpcValidatorInfo {
|
||||
readonly address: string;
|
||||
readonly pub_key: RpcPubkey;
|
||||
readonly voting_power: string;
|
||||
readonly proposer_priority?: string;
|
||||
}
|
||||
|
||||
function decodeValidatorInfo(data: RpcValidatorInfo): responses.Validator {
|
||||
export function decodeValidatorInfo(data: RpcValidatorInfo): responses.Validator {
|
||||
return {
|
||||
pubkey: decodePubkey(assertObject(data.pub_key)),
|
||||
votingPower: Integer.parse(assertNotEmpty(data.voting_power)),
|
||||
address: fromHex(assertNotEmpty(data.address)),
|
||||
proposerPriority: data.proposer_priority ? Integer.parse(data.proposer_priority) : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@ -716,7 +733,7 @@ function decodeTxEvent(data: RpcTxEvent): responses.TxEvent {
|
||||
|
||||
interface RpcValidatorsResponse {
|
||||
readonly block_height: string;
|
||||
readonly validators: readonly RpcValidatorUpdate[];
|
||||
readonly validators: readonly RpcValidatorInfo[];
|
||||
readonly count: string;
|
||||
readonly total: string;
|
||||
}
|
||||
@ -724,7 +741,7 @@ interface RpcValidatorsResponse {
|
||||
function decodeValidators(data: RpcValidatorsResponse): responses.ValidatorsResponse {
|
||||
return {
|
||||
blockHeight: Integer.parse(assertNotEmpty(data.block_height)),
|
||||
validators: assertArray(data.validators).map(decodeValidatorUpdate),
|
||||
validators: assertArray(data.validators).map(decodeValidatorInfo),
|
||||
count: Integer.parse(assertNotEmpty(data.count)),
|
||||
total: Integer.parse(assertNotEmpty(data.total)),
|
||||
};
|
||||
|
@ -56,7 +56,7 @@ export interface BlockResponse {
|
||||
export interface BlockResultsResponse {
|
||||
readonly height: number;
|
||||
readonly results: readonly TxData[];
|
||||
readonly validatorUpdates: readonly Validator[];
|
||||
readonly validatorUpdates: readonly ValidatorUpdate[];
|
||||
readonly consensusUpdates?: ConsensusParams;
|
||||
readonly beginBlockEvents: readonly Event[];
|
||||
readonly endBlockEvents: readonly Event[];
|
||||
@ -351,6 +351,11 @@ export interface Validator {
|
||||
readonly proposerPriority?: number;
|
||||
}
|
||||
|
||||
export interface ValidatorUpdate {
|
||||
readonly pubkey: ValidatorPubkey;
|
||||
readonly votingPower: number;
|
||||
}
|
||||
|
||||
export interface ConsensusParams {
|
||||
readonly block: BlockParams;
|
||||
readonly evidence: EvidenceParams;
|
||||
|
Loading…
x
Reference in New Issue
Block a user