Pull out and test makeCompactBitArray
This commit is contained in:
parent
5b8d3637ce
commit
27f34273f0
@ -4,12 +4,164 @@ import { assert } from "@cosmjs/utils";
|
||||
|
||||
import { MsgSend } from "./codec/cosmos/bank/v1beta1/tx";
|
||||
import { TxRaw } from "./codec/cosmos/tx/v1beta1/tx";
|
||||
import { makeMultisignedTx } from "./multisignature";
|
||||
import { makeCompactBitArray, makeMultisignedTx } from "./multisignature";
|
||||
import { SignerData, SigningStargateClient } from "./signingstargateclient";
|
||||
import { assertIsBroadcastTxSuccess } from "./stargateclient";
|
||||
import { faucet, pendingWithoutSimapp, simapp } from "./testutils.spec";
|
||||
|
||||
describe("multisignature", () => {
|
||||
describe("makeCompactBitArray", () => {
|
||||
it("works for 0 bits of different lengths", () => {
|
||||
expect(makeCompactBitArray([])).toEqual({ elems: new Uint8Array([]), extraBitsStored: 0 });
|
||||
expect(makeCompactBitArray([false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 1,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 3,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false, false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 4,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false, false, false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 5,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false, false, false, false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 6,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false, false, false, false, false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 7,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false, false, false, false, false, false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000]),
|
||||
extraBitsStored: 0,
|
||||
});
|
||||
expect(makeCompactBitArray([false, false, false, false, false, false, false, false, false])).toEqual({
|
||||
elems: new Uint8Array([0b00000000, 0b00000000]),
|
||||
extraBitsStored: 1,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, false, false, false, false, false, false, false]),
|
||||
).toEqual({ elems: new Uint8Array([0b00000000, 0b00000000]), extraBitsStored: 2 });
|
||||
});
|
||||
|
||||
it("works for 1 bits of different lengths", () => {
|
||||
expect(makeCompactBitArray([])).toEqual({ elems: new Uint8Array([]), extraBitsStored: 0 });
|
||||
expect(makeCompactBitArray([true])).toEqual({
|
||||
elems: new Uint8Array([0b10000000]),
|
||||
extraBitsStored: 1,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11100000]),
|
||||
extraBitsStored: 3,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11110000]),
|
||||
extraBitsStored: 4,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11111000]),
|
||||
extraBitsStored: 5,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true, true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11111100]),
|
||||
extraBitsStored: 6,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true, true, true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11111110]),
|
||||
extraBitsStored: 7,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true, true, true, true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11111111]),
|
||||
extraBitsStored: 0,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true, true, true, true, true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11111111, 0b10000000]),
|
||||
extraBitsStored: 1,
|
||||
});
|
||||
expect(makeCompactBitArray([true, true, true, true, true, true, true, true, true, true])).toEqual({
|
||||
elems: new Uint8Array([0b11111111, 0b11000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it("works for 1 bit in different places", () => {
|
||||
expect(
|
||||
makeCompactBitArray([true, false, false, false, false, false, false, false, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b10000000, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, true, false, false, false, false, false, false, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b01000000, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, true, false, false, false, false, false, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00100000, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, true, false, false, false, false, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00010000, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, false, true, false, false, false, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00001000, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, false, false, true, false, false, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00000100, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, false, false, false, true, false, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00000010, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, false, false, false, false, true, false, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00000001, 0b00000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, false, false, false, false, false, true, false]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00000000, 0b10000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
expect(
|
||||
makeCompactBitArray([false, false, false, false, false, false, false, false, false, true]),
|
||||
).toEqual({
|
||||
elems: new Uint8Array([0b00000000, 0b01000000]),
|
||||
extraBitsStored: 2,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("makeMultisignedTx", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutSimapp();
|
||||
|
||||
@ -9,6 +9,21 @@ import { AuthInfo, SignerInfo } from "./codec/cosmos/tx/v1beta1/tx";
|
||||
import { TxRaw } from "./codec/cosmos/tx/v1beta1/tx";
|
||||
import { StdFee } from "./fee";
|
||||
|
||||
export function makeCompactBitArray(bits: readonly boolean[]): CompactBitArray {
|
||||
const byteCount = Math.ceil(bits.length / 8);
|
||||
const extraBits = bits.length - Math.floor(bits.length / 8) * 8;
|
||||
const bytes = new Uint8Array(byteCount); // zero-filled
|
||||
|
||||
bits.forEach((value, index) => {
|
||||
const bytePos = Math.floor(index / 8);
|
||||
const bitPos = index % 8;
|
||||
// eslint-disable-next-line no-bitwise
|
||||
if (value) bytes[bytePos] |= 0b1 << (8 - 1 - bitPos);
|
||||
});
|
||||
|
||||
return CompactBitArray.fromPartial({ elems: bytes, extraBitsStored: extraBits });
|
||||
}
|
||||
|
||||
export function makeMultisignedTx(
|
||||
multisigPubkey: MultisigThresholdPubkey,
|
||||
sequence: number,
|
||||
@ -19,14 +34,13 @@ export function makeMultisignedTx(
|
||||
const addresses = Array.from(signatures.keys());
|
||||
const prefix = Bech32.decode(addresses[0]).prefix;
|
||||
|
||||
let bits = 0;
|
||||
const signers: boolean[] = Array(multisigPubkey.value.pubkeys.length).fill(false);
|
||||
const signaturesList = new Array<Uint8Array>();
|
||||
for (let i = 0; i < multisigPubkey.value.pubkeys.length; i++) {
|
||||
const signerAddress = pubkeyToAddress(multisigPubkey.value.pubkeys[i], prefix);
|
||||
const signature = signatures.get(signerAddress);
|
||||
if (signature) {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
bits |= 0b1 << (8 - 1 - i);
|
||||
signers[i] = true;
|
||||
signaturesList.push(signature);
|
||||
}
|
||||
}
|
||||
@ -35,10 +49,7 @@ export function makeMultisignedTx(
|
||||
publicKey: encodePubkey(multisigPubkey),
|
||||
modeInfo: {
|
||||
multi: {
|
||||
bitarray: CompactBitArray.fromPartial({
|
||||
elems: new Uint8Array([bits]),
|
||||
extraBitsStored: multisigPubkey.value.pubkeys.length,
|
||||
}),
|
||||
bitarray: makeCompactBitArray(signers),
|
||||
modeInfos: signaturesList.map((_) => ({ single: { mode: SignMode.SIGN_MODE_LEGACY_AMINO_JSON } })),
|
||||
},
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user