Skip to content

Commit

Permalink
Merge pull request #115 from casper-ecosystem/hotfix/support-invalid-…
Browse files Browse the repository at this point in the history
…zero-in-deploys

Support historical invalid byte representation of zero
  • Loading branch information
hoffmannjan authored Oct 11, 2021
2 parents 144a350 + d745042 commit 4f7cf7c
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to casper-js-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).

## 2.6.1

### Fixed

- Added workaround for historical deploys with invalid serialized `0`.

## 2.6.0

### Added
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "casper-js-sdk",
"version": "2.6.0",
"version": "2.6.1",
"license": "Apache 2.0",
"description": "SDK to interact with the Casper blockchain",
"homepage": "https://github.com/casper-ecosystem/casper-js-sdk#README.md",
Expand Down
43 changes: 33 additions & 10 deletions src/lib/CLValue/Numeric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,46 @@ import {
U256_ID,
U512_ID
} from './constants';
import { arrayEquals } from '../DeployUtil';

abstract class NumericBytesParser extends CLValueBytesParsers {
toBytes(value: Numeric): ToBytesResult {
// NOTE: this is for historicial deploys that had zero represented as `0100`.
// If there is zero in form of `0100` insted of `00` it should be serialized the same way to prevent changes in bodyHash.
if (
(value.bitSize === 128 ||
value.bitSize === 256 ||
value.bitSize === 512) &&
value.originalBytes &&
arrayEquals(value.originalBytes, Uint8Array.from([1, 0]))
) {
return Ok(value.originalBytes);
}

return Ok(toBytesNumber(value.bitSize, value.signed)(value.data));
}
}

abstract class Numeric extends CLValue {
data: BigNumber;
// NOTE: Original bytes are only used for legacy purposes.
originalBytes?: Uint8Array;
bitSize: number;
signed: boolean;

constructor(bitSize: number, isSigned: boolean, value: BigNumberish) {
constructor(
bitSize: number,
isSigned: boolean,
value: BigNumberish,
originalBytes?: Uint8Array
) {
super();
if (isSigned === false && Math.sign(value as number) < 0) {
throw new Error("Can't provide negative numbers with isSigned=false");
}
if (originalBytes) {
this.originalBytes = originalBytes;
}
this.bitSize = bitSize;
this.signed = isSigned;
this.data = BigNumber.from(value);
Expand Down Expand Up @@ -260,8 +283,8 @@ export class CLU128BytesParser extends NumericBytesParser {
}

export class CLU128 extends Numeric {
constructor(num: BigNumberish) {
super(128, false, num);
constructor(num: BigNumberish, originalBytes?: Uint8Array) {
super(128, false, num, originalBytes);
}

clType(): CLType {
Expand Down Expand Up @@ -292,8 +315,8 @@ export class CLU256BytesParser extends NumericBytesParser {
}

export class CLU256 extends Numeric {
constructor(num: BigNumberish) {
super(256, false, num);
constructor(num: BigNumberish, originalBytes?: Uint8Array) {
super(256, false, num, originalBytes);
}

clType(): CLType {
Expand Down Expand Up @@ -324,8 +347,8 @@ export class CLU512BytesParser extends NumericBytesParser {
}

export class CLU512 extends Numeric {
constructor(num: BigNumberish) {
super(512, false, num);
constructor(num: BigNumberish, originalBytes?: Uint8Array) {
super(512, false, num, originalBytes);
}

clType(): CLType {
Expand Down Expand Up @@ -359,13 +382,13 @@ const fromBytesBigInt = (
const value = BigNumber.from(bigIntBytes.slice().reverse());

if (bitSize === 128) {
return resultHelper(Ok(new CLU128(value)), remainder);
return resultHelper(Ok(new CLU128(value, rawBytes)), remainder);
}
if (bitSize === 256) {
return resultHelper(Ok(new CLU256(value)), remainder);
return resultHelper(Ok(new CLU256(value, rawBytes)), remainder);
}
if (bitSize === 512) {
return resultHelper(Ok(new CLU512(value)), remainder);
return resultHelper(Ok(new CLU512(value, rawBytes)), remainder);
}

return resultHelper(Err(CLErrorCodes.Formatting));
Expand Down
2 changes: 1 addition & 1 deletion src/lib/DeployUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ export const validateDeploy = (deploy: Deploy): Result<Deploy, string> => {
return Ok(deploy);
};

const arrayEquals = (a: Uint8Array, b: Uint8Array): boolean => {
export const arrayEquals = (a: Uint8Array, b: Uint8Array): boolean => {
return a.length === b.length && a.every((val, index) => val === b[index]);
};

Expand Down
2 changes: 1 addition & 1 deletion test/lib/byterepr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ describe(`numbers' toBytes`, () => {
).unwrap();
const clValBytes = CLValueParsers.toBytes(clVal).unwrap();

expect(clValFromBytes).to.deep.eq(clVal);
expect(clValFromBytes.value()).to.deep.eq(clVal.value());
expect(clValBytes).to.deep.eq(validBytes);
});

Expand Down

0 comments on commit 4f7cf7c

Please sign in to comment.