Skip to content

Commit

Permalink
Merge pull request #50 from casper-ecosystem/hotfix/dehumanizer-ttl
Browse files Browse the repository at this point in the history
Fixed problems with deployFromJson
  • Loading branch information
hoffmannjan authored May 10, 2021
2 parents c3e3ccf + e4b794c commit 9c4e70e
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ All notable changes to casper-client-sdk.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## 1.3.0

### Changed

- Removed EventStore from codebase.
- `CasperClient.getDeployByHashFromRPC` is now `CasperClient.getDeploy`.
- Fixed problems with `deployFromJson` caused by missing support for deserialization TTL values other than `ms`.

## 1.2.0

Expand Down
Empty file added index.js
Empty file.
41 changes: 34 additions & 7 deletions src/lib/DeployUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@ import { Result, Ok, Err } from 'ts-results';
const shortEnglishHumanizer = humanizeDuration.humanizer({
spacer: '',
serialComma: false,
conjunction: " ",
delimiter: " ",
language: 'shortEn',
languages: {
// https://docs.rs/humantime/2.0.1/humantime/fn.parse_duration.html
shortEn: {
y: () => 'y',
mo: () => 'M',
w: () => 'w',
d: () => 'd',
d: () => 'day',
h: () => 'h',
m: () => 'm',
s: () => 's',
Expand All @@ -65,13 +64,41 @@ const byteArrayJsonDeserializer: (str: string) => Uint8Array = (
};

/**
* Return a humanizer duration
* Returns a humanizer duration
* @param ttl in milliseconds
*/
export const humanizerTTL = (ttl: number) => {
return shortEnglishHumanizer(ttl);
};


/**
* Returns duration in ms
* @param ttl in humanized string
*/
export const dehumanizerTTL = (ttl: string): number => {
const dehumanizeUnit = (s: string): number => {
if (s.includes("ms")) {
return Number(s.replace('ms', ''));
};
if (s.includes('s') && !s.includes('m')) {
return Number(s.replace('s', '')) * 1000;
}
if (s.includes('m') && !s.includes('s')) {
return Number(s.replace('m', '')) * 60 * 1000;
}
if (s.includes('h')) {
return Number(s.replace('h', '')) * 60 * 60 * 1000;
}
if (s.includes('day')) {
return Number(s.replace('day', '')) * 24 * 60 * 60 * 1000;
}
throw Error("Unsuported TTL unit");
};

return ttl.split(" ").map(dehumanizeUnit).reduce((acc, val) => acc += val);
};

@jsonObject
export class DeployHeader implements ToBytes {
@jsonMember({
Expand All @@ -91,8 +118,8 @@ export class DeployHeader implements ToBytes {
public timestamp: number;

@jsonMember({
serializer: (n: number) => String(n) + 'ms',
deserializer: (s: string) => Number(s.replace('ms', ''))
serializer: humanizerTTL,
deserializer: dehumanizerTTL
})
public ttl: number;

Expand Down
85 changes: 84 additions & 1 deletion test/lib/CasperClient.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect } from 'chai';
import { CasperClient } from '../../src/lib/CasperClient';
import { Deploy } from '../../src/lib/DeployUtil';
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
Expand Down Expand Up @@ -116,7 +117,7 @@ describe('CasperClient', () => {
expect(loadedKeyPair.privateKey).to.deep.equal(edKeyPair.privateKey);
});

it('should create a HK wallet and derive child account correctly', function () {
it('should create a HK wallet and derive child account correctly', function() {
const seed =
'fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542';
const hdKey = casperClient.newHdWallet(decodeBase16(seed));
Expand All @@ -129,4 +130,86 @@ describe('CasperClient', () => {
const signature2 = secpKey2.sign(msg);
expect(secpKey2.verify(signature2, msg)).to.be.equal(true);
});

it('should create deploy from Deploy JSON with ttl in minutes', function() {
const json = {
deploy: {
approvals: [
{
signature: '130 chars',
signer:
'012d9dded24145247421eb8b904dda5cce8a7c77ae18de819a25628c4a01adbf76'
}
],
hash:
'ceaaa76e7fb850a09d5c9d16ac995cb52eff2944066cfd8cac27f3595f11b652',
header: {
account:
'012d9dded24145247421eb8b904dda5cce8a7c77ae18de819a25628c4a01adbf76',
body_hash:
'0e68d66a9dfab19bb1898d5f4d11a4f55dd06a0cae3917afc1eae4a5b56352e7',
chain_name: 'casper-test',
dependencies: [],
gas_price: 1,
timestamp: '2021-05-06T07:49:32.583Z',
ttl: '30m'
},
payment: {
ModuleBytes: {
args: [
[
'amount',
{
bytes: '0500e40b5402',
cl_type: 'U512',
parsed: '10000000000'
}
]
],
module_bytes: ''
}
},
session: {
Transfer: {
args: [
[
'amount',
{
bytes: '0500743ba40b',
cl_type: 'U512',
parsed: '50000000000'
}
],
[
'target',
{
bytes:
'1541566bdad3a3cfa9eb4cba3dcf33ee6583e0733ae4b2ccdfe92cd1bd92ee16',
cl_type: {
ByteArray: 32
},
parsed:
'1541566bdad3a3cfa9eb4cba3dcf33ee6583e0733ae4b2ccdfe92cd1bd92ee16'
}
],
[
'id',
{
bytes: '01a086010000000000',
cl_type: {
Option: 'U64'
},
parsed: 100000
}
]
]
}
}
}
};
const fromJson = casperClient.deployFromJson(json);

expect(fromJson).to.be.an.instanceof(Deploy);
expect(fromJson!.header.ttl).to.be.eq(1800000);
});
});
33 changes: 33 additions & 0 deletions test/lib/DeployUtil.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, assert } from 'chai';
import { Keys, DeployUtil, CLValue } from '../../src/lib';
import { humanizerTTL, dehumanizerTTL } from '../../src/lib/DeployUtil';
import { TypedJSON } from 'typedjson';

const testDeploy = () => {
Expand Down Expand Up @@ -229,6 +230,38 @@ describe('DeployUtil', () => {
assert.isUndefined(DeployUtil.deployFromJson(json));
});

it('Should convert ms to humanized string', function () {
const strTtl30m = humanizerTTL(1800000);
const strTtl45m = humanizerTTL(2700000);
const strTtl1h = humanizerTTL(3600000);
const strTtl1h30m = humanizerTTL(5400000);
const strTtl1day = humanizerTTL(86400000);
const strTtlCustom = humanizerTTL(86103000);

expect(strTtl30m).to.be.eq("30m");
expect(strTtl45m).to.be.eq("45m");
expect(strTtl1h).to.be.eq("1h");
expect(strTtl1h30m).to.be.eq("1h 30m");
expect(strTtl1day).to.be.eq("1day");
expect(strTtlCustom).to.be.eq("23h 55m 3s");
});

it('Should convert humanized string to ms', function () {
const msTtl30m = dehumanizerTTL("30m");
const msTtl45m = dehumanizerTTL("45m");
const msTtl1h = dehumanizerTTL("1h");
const msTtl1h30m = dehumanizerTTL("1h 30m");
const msTtl1day = dehumanizerTTL("1day");
const msTtlCustom = dehumanizerTTL("23h 55m 3s");

expect(msTtl30m).to.be.eq(1800000);
expect(msTtl45m).to.be.eq(2700000);
expect(msTtl1h).to.be.eq(3600000);
expect(msTtl1h30m).to.be.eq(5400000);
expect(msTtl1day).to.be.eq(86400000);
expect(msTtlCustom).to.be.eq(86103000);
});

it('Should not allow to create new transfer without providing transfer-id', () => {
const recipientKey = Keys.Ed25519.new();
const transferAmount = 10;
Expand Down

0 comments on commit 9c4e70e

Please sign in to comment.