Skip to content

Commit

Permalink
Merge pull request #476 from casper-ecosystem/clValue-enhancement
Browse files Browse the repository at this point in the history
Fixed Tuple3 constructor inconsistency, aligned Numerics CLValue by value type
  • Loading branch information
alexmyshchyshyn authored Dec 23, 2024
2 parents 7b9905e + 1b702e7 commit 11b671b
Show file tree
Hide file tree
Showing 33 changed files with 458 additions and 628 deletions.
3 changes: 1 addition & 2 deletions src/types/Deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
TransferDeployItem
} from './ExecutableDeployItem';
import { Deploy, DeployHeader } from './Deploy';
import { PrivateKey } from './keypair/PrivateKey';
import { KeyAlgorithm } from './keypair/Algorithm';
import { KeyAlgorithm, PrivateKey } from './keypair';
import { Duration, Timestamp } from './Time';
import { Hash } from './key';
import { dehumanizerTTL, humanizerTTL } from './SerializationUtils';
Expand Down
9 changes: 3 additions & 6 deletions src/types/EraEnd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import {
} from 'typedjson';
import { PublicKey } from './keypair';
import { ValidatorWeightEraEnd } from './ValidatorWeight';
import {
CLValueUInt512,
deserializeRewards,
serializeRewards
} from './clvalue';
import { CLValueUInt512 } from './clvalue';
import { deserializeRewards, serializeRewards } from './SerializationUtils';

/**
* Class representing the rewards associated with a validator in a given era.
Expand Down Expand Up @@ -252,7 +249,7 @@ export class EraEnd {
@jsonMapMember(String, CLValueUInt512, {
name: 'rewards',
deserializer: deserializeRewards,
serializer: (map: Map<string, CLValueUInt512[]>) => serializeRewards(map),
serializer: (map: Map<string, CLValueUInt512[]>) => serializeRewards(map)
})
public rewards: Map<string, CLValueUInt512[]>;

Expand Down
2 changes: 1 addition & 1 deletion src/types/PricingMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class PaymentLimitedMode {
);
calltableSerializer.addField(
3,
CLValueBool.fromBoolean(this.standardPayment).bytes()
CLValueBool.newCLValueBool(this.standardPayment).bytes()
);

return calltableSerializer.toBytes();
Expand Down
36 changes: 36 additions & 0 deletions src/types/SerializationUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TypedJSON } from 'typedjson';
import humanizeDuration from 'humanize-duration';
import { Args } from './Args';
import { Conversions } from './Conversions';
import { CLValueUInt512 } from './clvalue';

/**
* Serializes a `Uint8Array` into a hexadecimal string.
Expand Down Expand Up @@ -172,3 +173,38 @@ export const serializeArgs = (ra: Args, asNamed = false) => {

return argsArray;
};

/**
* Deserializes an array of rewards into a Map.
* @param arr - The array to be deserialized, where each element is a tuple containing a key and an array of rewards.
* @returns A Map where each key corresponds to an array of CLValueUInt512 rewards.
* @throws Will throw an error if duplicate keys are detected.
*/
export const deserializeRewards = (arr: any) => {
const parsed = new Map(
Array.from(arr, ([key, value]) => {
const valuesArray = value.map((item: any) =>
CLValueUInt512.fromJSON(item)
);
return [key, valuesArray];
})
);

if (parsed.size !== Array.from(arr).length) {
throw Error(`Duplicate key exists.`);
}

return parsed;
};

/**
* Serializes a Map of rewards into an array format suitable for JSON storage.
* @param map - A Map where each key corresponds to an array of CLValueUInt512 rewards.
* @returns An array where each element is a tuple containing a key and an array of rewards in JSON format.
*/
export const serializeRewards = (map: Map<string, CLValueUInt512[]>) => {
return Array.from(map, ([key, value]) => {
const serializedValue = value.map(item => item.toJSON());
return [key, serializedValue];
});
};
2 changes: 1 addition & 1 deletion src/types/clvalue/Bool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('CLBool', () => {
});

it('toJSON() / fromJSON() do proper bytes serialization', () => {
const myBool = CLValueBool.fromBoolean(false);
const myBool = CLValueBool.newCLValueBool(false);
const json = CLValueParser.toJSON(myBool);
const expectedJson = JSON.parse('{"bytes":"00","cl_type":"Bool"}');

Expand Down
2 changes: 1 addition & 1 deletion src/types/clvalue/Bool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class CLValueBool {
* @param val - The boolean value to be stored in the CLValue.
* @returns A new CLValue instance encapsulating the boolean value.
*/
public static fromBoolean(val: boolean): CLValue {
public static newCLValueBool(val: boolean): CLValue {
const res = new CLValue(CLTypeBool);
res.bool = new CLValueBool(val);
return res;
Expand Down
18 changes: 10 additions & 8 deletions src/types/clvalue/CLValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ import {
} from './cltype';
import { URef, Key } from '../key';
import { PublicKey } from '../keypair';
import { CLValueUInt8 } from './Uint8';
import { CLValueInt64 } from './Int64';
import { CLValueInt32 } from './Int32';
import {
CLValueUInt8,
CLValueInt64,
CLValueInt32,
CLValueUInt32,
CLValueUInt64,
CLValueUInt128,
CLValueUInt256,
CLValueUInt512
} from './Numeric';
import { CLValueBool } from './Bool';
import { CLValueUInt32 } from './Uint32';
import { CLValueUInt64 } from './Uint64';
import { CLValueUInt128 } from './Uint128';
import { CLValueUInt256 } from './Uint256';
import { CLValueUInt512 } from './Uint512';
import { CLValueUnit } from './Unit';
import { CLValueOption } from './Option';
import { CLValueList } from './List';
Expand Down
10 changes: 5 additions & 5 deletions src/types/clvalue/List.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect } from 'chai';
import { CLTypeBool, CLTypeList, CLTypeUInt32 } from './cltype';
import { concat } from '@ethersproject/bytes';
import { toBytesU32 } from '../ByteConverters';
import { CLValueUInt32 } from './Uint32';
import { CLValueUInt32 } from './Numeric/Uint32';
import { CLValueList } from './List';
import { BigNumber } from '@ethersproject/bignumber';
import { CLValue } from './CLValue';
Expand Down Expand Up @@ -108,8 +108,8 @@ describe('CLValueList with boolean values', () => {

beforeEach(() => {
boolTypeList = new CLTypeList(CLTypeBool);
trueElement = CLValueBool.fromBoolean(true);
falseElement = CLValueBool.fromBoolean(false);
trueElement = CLValueBool.newCLValueBool(true);
falseElement = CLValueBool.newCLValueBool(false);
clValueBoolList = new CLValueList(boolTypeList, [
trueElement,
falseElement
Expand All @@ -135,7 +135,7 @@ describe('CLValueList with boolean values', () => {
});

it('should add a boolean element to the list when calling append()', () => {
const newElement = CLValueBool.fromBoolean(true);
const newElement = CLValueBool.newCLValueBool(true);
clValueBoolList.append(newElement);
expect(clValueBoolList.elements).to.deep.equal([
trueElement,
Expand All @@ -151,7 +151,7 @@ describe('CLValueList with boolean values', () => {
});

it('should throw error if index is out of bounds in set() for boolean list', () => {
const newElement = CLValueBool.fromBoolean(false);
const newElement = CLValueBool.newCLValueBool(false);
expect(() => clValueBoolList.set(2, newElement)).to.throw(
'List index out of bounds.'
);
Expand Down
4 changes: 2 additions & 2 deletions src/types/clvalue/List.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { concat } from '@ethersproject/bytes';

import { CLType, CLTypeList } from './cltype';
import { CLValue, IResultWithBytes } from './CLValue';
import { CLValueUInt32 } from './Uint32';
import { CLValueUInt32 } from './Numeric';
import { CLValueParser } from './Parser';
import { toBytesU32 } from '../ByteConverters';

Expand Down Expand Up @@ -152,7 +152,7 @@ export class CLValueList {
clType: CLTypeList
): IResultWithBytes<CLValueList> {
const { result: u32, bytes: u32Bytes } = CLValueUInt32.fromBytes(source);
const size = u32.getValue().toNumber();
const size = u32.toNumber();
let remainder = u32Bytes;
const elements: CLValue[] = [];

Expand Down
4 changes: 2 additions & 2 deletions src/types/clvalue/Map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { concat } from '@ethersproject/bytes';
import { CLType, CLTypeMap } from './cltype';
import { CLValue, IResultWithBytes } from './CLValue';
import { CLValueTuple2 } from './Tuple2';
import { CLValueUInt32 } from './Uint32';
import { CLValueUInt32 } from './Numeric';
import { CLValueParser } from './Parser';
import { toBytesU32 } from '../ByteConverters';

Expand Down Expand Up @@ -194,7 +194,7 @@ export class CLValueMap {
const mapResult = new CLValueMap(mapType);

const { result: u32, bytes: u32Bytes } = CLValueUInt32.fromBytes(bytes);
const size = u32.getValue().toNumber();
const size = u32.toNumber();
let remainder = u32Bytes;

if (size === 0) {
Expand Down
56 changes: 56 additions & 0 deletions src/types/clvalue/Numeric/Abstract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { BigNumber, BigNumberish } from '@ethersproject/bignumber';

/**
* Abstract class representing a numeric value in the Casper type system.
* Provides common methods and properties for numeric types.
*/
export abstract class CLValueNumeric {
protected value: BigNumberish;

/**
* The constructor is protected to ensure this class cannot be instantiated directly.
* Subclasses can call this constructor using `super`.
*/
protected constructor(value: BigNumberish) {
this.value = value;
}

/**
* Converts the numeric value to its byte representation.
* Must be implemented by subclasses.
*/
public abstract bytes(): Uint8Array;

/**
* Provides a string representation of the numeric value.
* @returns The string representation of the value.
*/
public toString(): string {
return this.value.toString();
}

/**
* Converts the numeric value to a JavaScript number.
* @returns The numeric value as a JavaScript number.
*/
public toNumber(): number {
const bigNumber = BigNumber.from(this.value);
return bigNumber.toNumber();
}

/**
* Converts the instance to a JSON-compatible string.
* @returns {string} The string representation of the instance.
*/
public toJSON(): string {
return this.toString();
}

/**
* Retrieves the numeric value.
* @returns The numeric representation of the value.
*/
public getValue(): BigNumberish {
return this.value;
}
}
42 changes: 6 additions & 36 deletions src/types/clvalue/Int32.ts → src/types/clvalue/Numeric/Int32.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import { BigNumber, BigNumberish } from '@ethersproject/bignumber';

import { CLTypeInt32, Int32ByteSize } from './cltype';
import { CLValue, IResultWithBytes } from './CLValue';
import { toBytesI32 } from '../ByteConverters';
import { CLTypeInt32, Int32ByteSize } from '../cltype';
import { CLValue, IResultWithBytes } from '../CLValue';
import { toBytesI32 } from '../../ByteConverters';
import { CLValueNumeric } from './Abstract';

/**
* Represents a 32-bit signed integer value in the Casper type system.
* This class provides methods for handling 32-bit integers, including byte conversion and CLValue integration.
*/
export class CLValueInt32 {
private value: BigNumberish;

/**
* Initializes a new instance of the CLValueInt32 class.
* @param value - The 32-bit integer value to be stored in the CLValueInt32.
*/
export class CLValueInt32 extends CLValueNumeric {
constructor(value: BigNumberish) {
this.value = value;
super(value);
}

/**
Expand All @@ -27,31 +22,6 @@ export class CLValueInt32 {
return toBytesI32(this.value);
}

/**
* Provides a string representation of the Int32 value.
* @returns The string representation of the stored value.
*/
public toString(): string {
return this.value.toString();
}

/**
* Converts the instance to a JSON-compatible string.
*
* @returns {string} The string representation of the instance.
*/
public toJSON(): string {
return this.toString();
}

/**
* Retrieves the numeric value of the Int32.
* @returns The numeric representation of the value.
*/
public getValue(): BigNumberish {
return this.value;
}

/**
* Creates a new CLValue instance with an Int32 value.
* @param val - The 32-bit integer to be encapsulated in a CLValue.
Expand Down
42 changes: 6 additions & 36 deletions src/types/clvalue/Int64.ts → src/types/clvalue/Numeric/Int64.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import { BigNumber, BigNumberish } from '@ethersproject/bignumber';

import { CLTypeInt64, Int64ByteSize } from './cltype';
import { CLValue, IResultWithBytes } from './CLValue';
import { toBytesI64 } from '../ByteConverters';
import { CLTypeInt64, Int64ByteSize } from '../cltype';
import { CLValue, IResultWithBytes } from '../CLValue';
import { toBytesI64 } from '../../ByteConverters';
import { CLValueNumeric } from './Abstract';

/**
* Represents a 64-bit signed integer value in the Casper type system.
* This class provides methods for handling 64-bit integers, including byte conversion and CLValue integration.
*/
export class CLValueInt64 {
private value: BigNumberish;

/**
* Initializes a new instance of the CLValueInt64 class.
* @param value - The value to be stored in the CLValueInt64. Accepts any BigNumberish type.
*/
export class CLValueInt64 extends CLValueNumeric {
constructor(value: BigNumberish) {
this.value = value;
super(value);
}

/**
Expand All @@ -27,31 +22,6 @@ export class CLValueInt64 {
return toBytesI64(this.value);
}

/**
* Provides a string representation of the Int64 value.
* @returns The string representation of the stored value.
*/
public toString(): string {
return this.value.toString();
}

/**
* Converts the instance to a JSON-compatible string.
*
* @returns {string} The string representation of the instance.
*/
public toJSON(): string {
return this.toString();
}

/**
* Retrieves the bigint value of the Int64.
* @returns The bigint representation of the stored value.
*/
public getValue(): BigNumberish {
return this.value;
}

/**
* Creates a new CLValue instance with an Int64 value.
* @param val - The value to be stored in the Int64. Accepts any BigNumberish type.
Expand Down
Loading

0 comments on commit 11b671b

Please sign in to comment.