add nonce encode/decode functions and test

This commit is contained in:
Ethan Frey 2020-01-23 15:08:00 +01:00
parent 95722a0495
commit 5074a8c8d3
4 changed files with 59 additions and 4 deletions

View File

@ -54,8 +54,6 @@ export class CosmosCodec implements TxCodec {
}
public bytesToSign(unsigned: UnsignedTransaction, nonce: Nonce): SigningJob {
console.log("nonce:", nonce);
// ohhh... this is a bug!!!
const accountNumber = 0;
const memo = (unsigned as any).memo;
const built = buildUnsignedTx(unsigned, this.tokens);

15
src/types.spec.ts Normal file
View File

@ -0,0 +1,15 @@
/* eslint-disable @typescript-eslint/camelcase */
import { accountToNonce, nonceToAccountNumber, nonceToSequence } from "./types";
describe("nonceEncoding", () => {
it("works for input in range", () => {
const nonce = accountToNonce("1234", "7890");
expect(nonceToAccountNumber(nonce)).toEqual("1234");
expect(nonceToSequence(nonce)).toEqual("7890");
});
it("errors on input too large", () => {
expect(() => accountToNonce("1234567890", "7890")).toThrow();
expect(() => accountToNonce("178", "97320247923")).toThrow();
});
});

View File

@ -1,4 +1,4 @@
import { Amount, Token } from "@iov/bcp";
import { Amount, Nonce, Token } from "@iov/bcp";
import amino from "@tendermint/amino-js";
export type AminoTx = amino.Tx & { readonly value: amino.StdTx };
@ -40,3 +40,42 @@ export function coinToAmount(tokens: TokenInfos, coin: amino.Coin): Amount {
quantity: coin.amount,
};
}
// tslint:disable-next-line:no-bitwise
const maxAcct = 1 << 23;
// tslint:disable-next-line:no-bitwise
const maxSeq = 1 << 20;
// this (lossily) encodes the two pieces of info (uint64) needed to sign into
// one (53-bit) number. Cross your fingers.
export function accountToNonce(accountNumber: string, sequence: string): Nonce {
const acct = parseInt(accountNumber, 10);
const seq = parseInt(sequence, 10);
// we allow 23 bits (8 million) for accounts, and 20 bits (1 million) for tx/account
// let's fix this soon
if (acct > maxAcct) {
throw new Error("Account number is greater than 2^23, must update Nonce handler");
}
if (seq > maxSeq) {
throw new Error("Sequence is greater than 2^20, must update Nonce handler");
}
const val = acct * maxSeq + seq;
return val as Nonce;
}
// this extracts info from nonce for signing
export function nonceToAccountNumber(nonce: Nonce): string {
const acct = nonce / maxSeq;
if (acct > maxAcct) {
throw new Error("Invalid Nonce, account number is higher than can safely be encoded in Nonce");
}
return Math.round(acct).toString();
}
// this extracts info from nonce for signing
export function nonceToSequence(nonce: Nonce): string {
const seq = nonce % maxSeq;
return Math.round(seq).toString();
}

5
types/types.d.ts vendored
View File

@ -1,4 +1,4 @@
import { Amount, Token } from "@iov/bcp";
import { Amount, Token, Nonce } from "@iov/bcp";
import amino from "@tendermint/amino-js";
export declare type AminoTx = amino.Tx & {
readonly value: amino.StdTx;
@ -10,3 +10,6 @@ export interface TokenInfo extends Token {
export declare type TokenInfos = ReadonlyArray<TokenInfo>;
export declare function amountToCoin(lookup: ReadonlyArray<TokenInfo>, amount: Amount): amino.Coin;
export declare function coinToAmount(tokens: TokenInfos, coin: amino.Coin): Amount;
export declare function accountToNonce(accountNumber: string, sequence: string): Nonce;
export declare function nonceToAccountNumber(nonce: Nonce): string;
export declare function nonceToSequence(nonce: Nonce): string;