Pull out and test makeCompactBitArray

This commit is contained in:
Simon Warta 2021-03-24 11:05:28 +01:00
parent 5b8d3637ce
commit 27f34273f0
2 changed files with 171 additions and 8 deletions

View File

@ -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();

View File

@ -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 } })),
},
},