Skip to content

Commit

Permalink
Merge pull request #31 from Chia-Mine/v1.0.8
Browse files Browse the repository at this point in the history
V1.0.8
  • Loading branch information
ChiaMineJP authored Sep 4, 2021
2 parents a9fdc12 + 861eb86 commit a74dccc
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 20 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## [1.0.8]
This version is compatible with [`2722c78ddb92f067c5025196f397e4d2955f9053`](https://github.com/Chia-Network/clvm/tree/2722c78ddb92f067c5025196f397e4d2955f9053) of [clvm](https://github.com/Chia-Network/clvm)

### Fixed
- Fixed typo in error message
- Fixed an issue where `op_substr` did not work as expected.
- Fixed an issue where cost calculation for `op_subtract` was not correct.
- Fixed `limbs_for_int` return wrong value when argument is `0`.
- Fixed an issue where `Bytes` comparison returns wrong result in some cases.
- Fixed an issue where `op_softfork` crashed with argument atom larger than or equal to 53bit.
- Fixed G1Element error message.

## [1.0.7]
This version is compatible with [`2722c78ddb92f067c5025196f397e4d2955f9053`](https://github.com/Chia-Network/clvm/tree/2722c78ddb92f067c5025196f397e4d2955f9053) of [clvm](https://github.com/Chia-Network/clvm)

Expand Down Expand Up @@ -227,6 +239,7 @@ At this version, I've managed to improve test complete time to `79s` -> `2s` by
Initial (beta) release.

<!--[Unreleased]: https://github.com/Chia-Mine/clvm-js/compare/v0.0.1...v0.0.2-->
[1.0.8]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.7...v1.0.8
[1.0.7]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.6...v1.0.7
[1.0.6]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.5...v1.0.6
[1.0.5]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.4...v1.0.5
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": "clvm",
"version": "1.0.7",
"version": "1.0.8",
"author": "ChiaMineJP <[email protected]>",
"description": "Javascript implementation of chia lisp",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion src/__bls_signatures__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function assert_G1Element_valid(bytes: Uint8Array){
const BLSModule = getBLSModule();
const {G1Element} = BLSModule;
if(bytes.length !== G1Element.SIZE){
throw new Error("G1Element: Invalid size");
throw new Error("Length of bytes object not equal to G1Element::SIZE");
}

if((bytes[0] & 0xc0) === 0xc0){ // representing infinity
Expand Down
44 changes: 33 additions & 11 deletions src/__type_compatibility__.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Word32Array} from "jscrypto/Word32Array";
import {SHA256} from "jscrypto/SHA256";
import {None} from "./__python_types__";
import {G1Element} from "@chiamine/bls-signatures";
import {bigint_from_bytes} from "./casts";

export function to_hexstr(r: Uint8Array) {
return (new Word32Array(r)).toString();
Expand Down Expand Up @@ -238,25 +239,46 @@ export class Bytes {
* @param other
*/
public compare(other: Bytes): -1|0|1 {
if(this.length !== other.length){
return this.length > other.length ? 1 : -1;
if(this.length === 0 && other.length === 0){
return 0;
}
else if(this.length * other.length === 0){ // Either length of this or other is zero.
return this.length > 0 ? 1 : -1;
}
const self_raw_byte = this._b;
const dv_self = new DataView(self_raw_byte.buffer, self_raw_byte.byteOffset, self_raw_byte.byteLength);
const self_byteLength = self_raw_byte.byteLength;
const dv_self = new DataView(self_raw_byte.buffer, self_raw_byte.byteOffset, self_byteLength);
const other_raw_byte = other.raw();
const dv_other = new DataView(other_raw_byte.buffer, other_raw_byte.byteOffset, other_raw_byte.byteLength);

const ui32MaxCount = (this.length / 4) | 0;
for(let i=0;i<ui32MaxCount;i++){
const ui32_self = dv_self.getUint32(i*4);
const ui32_other = dv_other.getUint32(i*4);
const other_byteLength = other_raw_byte.byteLength;
const dv_other = new DataView(other_raw_byte.buffer, other_raw_byte.byteOffset, other_byteLength);

// const minByteLength = Math.min(self_byteLength, other_byteLength);
const minByteLength = Math.min(self_byteLength, other_byteLength) - 4;
const ui32MaxCount = (Math.max(self_byteLength, other_byteLength) / 4) | 0;
let offset = 0;
for(offset=0;offset<ui32MaxCount;offset++){
const k = offset*4;
// if(k + 4 > minByteLength){ // k > minByteLength - 4 ==(optimize)==> minByteLength = minByteLength - 4
if(k > minByteLength){
break;
}
const ui32_self = dv_self.getUint32(k);
const ui32_other = dv_other.getUint32(k);
if(ui32_self !== ui32_other){
return ui32_self > ui32_other ? 1 : -1;
}
}

const offset = ui32MaxCount*4;
for(let i=offset;i<this.length;i++){
offset = offset*4;
const ui8MaxCount = Math.max(self_byteLength, other_byteLength);
for(let i=offset;i<ui8MaxCount;i++){
const k = i + 1;
if(k > self_byteLength){
return -1;
}
else if(k > other_byteLength){
return 1;
}
const ui8_self = dv_self.getUint8(i);
const ui8_other = dv_other.getUint8(i);
if(ui8_self !== ui8_other){
Expand Down
3 changes: 3 additions & 0 deletions src/casts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,5 +232,8 @@ export function bigint_to_bytes(v: bigint, option?: Partial<TConvertOption>): By
* @param {number} v
*/
export function limbs_for_int(v: number|bigint): number {
if(v === 0 || v === BigInt(0)){
return 0;
}
return ((v >= 0 ? v : -v).toString(2).length + 7) >> 3;
}
16 changes: 11 additions & 5 deletions src/more_ops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function* args_as_int32(op_name: string, args: SExp){
throw new EvalError(`${op_name} requires int32 args`, arg);
}
else if(arg.atom.length > 4){
throw new EvalError(`${op_name} requires int32 args (with no leading zeros`, arg);
throw new EvalError(`${op_name} requires int32 args (with no leading zeros)`, arg);
}
yield arg.as_int();
}
Expand Down Expand Up @@ -154,7 +154,7 @@ export function op_subtract(args: SExp){
total += sign * r;
sign = BigInt(-1);
arg_size += l;
cost += ARITH_COST_PER_BYTE;
cost += ARITH_COST_PER_ARG;
}
cost += arg_size * ARITH_COST_PER_BYTE;
return malloc_cost(cost, SExp.to(total));
Expand Down Expand Up @@ -273,7 +273,8 @@ export function op_point_add(items: SExp){
cost += POINT_ADD_COST_PER_ARG;
}
catch(e){
throw new EvalError(`point_add expects blob, got ${_.atom}: ${JSON.stringify(e)}`, items);
const eMsg = e instanceof Error ? e.message : typeof e === "string" ? e : JSON.stringify(e);
throw new EvalError(`point_add expects blob, got ${_}: ${eMsg}`, items);
}
}
return malloc_cost(cost, SExp.to(p));
Expand Down Expand Up @@ -321,7 +322,7 @@ export function op_substr(args: SExp){
throw new EvalError("invalid indices for substr", args);
}

const s = s0.subarray(i1, i2);
const s = s0.subarray(i1, i2-i1);
const cost = 1;
return t(cost, SExp.to(s));
}
Expand Down Expand Up @@ -493,7 +494,12 @@ export function op_softfork(args: SExp){
if(!isAtom(a)){
throw new EvalError("softfork requires int args", a);
}
const cost = a.as_int();
const cost_bigint = a.as_bigint();
if(cost_bigint > BigInt(Number.MAX_SAFE_INTEGER)){
throw new Error("Cost greater than 2**53-1 is not supported at this time");
}

const cost = Number(cost_bigint);
if(cost < 1){
throw new EvalError("cost must be > 0", args);
}
Expand Down
2 changes: 1 addition & 1 deletion src/operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export type KEYWORDS = keyof typeof KEYWORD_TO_ATOM;
export function* args_len(op_name: string, args: SExp){
for(const arg of args.as_iter()){
if(arg.pair){
throw new EvalError(`${op_name} requires int args"`, arg);
throw new EvalError(`${op_name} requires int args`, arg);
}
yield (arg.atom as Bytes).length;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/_casts_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ describe("bigint_to_bytes", () => {
});

test("limbs_for_int", () => {
expect(limbs_for_int(0)).toBe(1);
expect(limbs_for_int(0)).toBe(0);
expect(limbs_for_int(1)).toBe(1);
expect(limbs_for_int(-255)).toBe(1);
expect(limbs_for_int(255)).toBe(1);
Expand Down
58 changes: 58 additions & 0 deletions tests/_type_compatibility_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {Bytes, b, h} from "../src/__type_compatibility__";

describe("Bytes", () => {
test("0x00 > b('')", () => {
expect(h("0x00").compare(b(""))).toBe(1);
});
test("b('') < 0x00", () => {
expect(b("").compare(h("0x00"))).toBe(-1);
});
test("0x00 < 0x0000", () => {
expect(h("0x00").compare(h("0x0000"))).toBe(-1);
});
test("0x1000 > 0x10", () => {
expect(h("0x1000").compare(h("0x10"))).toBe(1);
});
test("0x0010 < 0x10", () => {
expect(h("0x0010").compare(h("0x10"))).toBe(-1);
});
test("0x1000 < 0x20", () => {
expect(h("0x1000").compare(h("0x20"))).toBe(-1);
});
test("0x2000 > 0x20", () => {
expect(h("0x2000").compare(h("0x20"))).toBe(1);
});
test("0x2000 < 0x21", () => {
expect(h("0x2000").compare(h("0x21"))).toBe(-1);
});
test("0x0011 > 0x0010", () => {
expect(h("0x0011").compare(h("0x0010"))).toBe(1);
});
test("0x4433221144332211 == 0x4433221144332211", () => {
expect(h("0x4433221144332211").compare(h("0x4433221144332211"))).toBe(0);
});
test("0x4433221144332211 > 0x4433221144002211", () => {
expect(h("0x4433221144332211").compare(h("0x4433221144002211"))).toBe(1);
});
test("0x4433221144332211 < 0x4433221144332212", () => {
expect(h("0x4433221144332211").compare(h("0x4433221144332212"))).toBe(-1);
});
test("0x4433221144332212 > 0x4433221144332211", () => {
expect(h("0x4433221144332212").compare(h("0x4433221144002211"))).toBe(1);
});
test("0xfedcba9876543210fedcba9876543210fedcba9876543210 == 0xfedcba9876543210fedcba9876543210fedcba9876543210", () => {
expect(h("0xfedcba9876543210fedcba9876543210fedcba9876543210").compare(h("0xfedcba9876543210fedcba9876543210fedcba9876543210"))).toBe(0);
});
test("0xfedcba9876543210fedcbaAA76543210fedcba9876543210 > 0xfedcba9876543210fedcba9876543210fedcba9876543210", () => {
expect(h("0xfedcba9876543210fedcbaAA76543210fedcba9876543210").compare(h("0xfedcba9876543210fedcba9876543210fedcba9876543210"))).toBe(1);
});
test("0xfedcba9876543210fedcba9876543210fedcba9876543210 < 0xffdcba987654", () => {
expect(h("0xfedcba9876543210fedcba9876543210fedcba9876543210").compare(h("0xffdcba987654"))).toBe(-1);
});
test("b('') == b('')", () => {
expect(b("").compare(b(""))).toBe(0);
});
test("0x414243 == b('ABC')", () => {
expect(h("0x414243").compare(b("ABC"))).toBe(0);
});
})

0 comments on commit a74dccc

Please sign in to comment.