Skip to content

Commit

Permalink
Merge pull request #26 from Chia-Mine/v1.0.4
Browse files Browse the repository at this point in the history
V1.0.4
  • Loading branch information
ChiaMineJP authored Aug 13, 2021
2 parents a08bf80 + f904710 commit 8fbe3fd
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 66 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [1.0.4]
This version is compatible with [`ab4560900cf475ff515054bec0ca9a4491aca366`](https://github.com/Chia-Network/clvm/tree/ab4560900cf475ff515054bec0ca9a4491aca366) of [[email protected]](https://github.com/Chia-Network/clvm)

### Fixed
- Fixed an issue where `int_from_bytes` and `bigint_from_bytes` returned always signed int/bigint.
- Fixed an issue where `int_to_bytes` and `bigint_to_bytes` blindly recognized the argument as a signed int/bigint.

## [1.0.3]
This version is compatible with [`ab4560900cf475ff515054bec0ca9a4491aca366`](https://github.com/Chia-Network/clvm/tree/ab4560900cf475ff515054bec0ca9a4491aca366) of [[email protected]](https://github.com/Chia-Network/clvm)

Expand Down Expand Up @@ -187,6 +194,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.4]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.3...v1.0.4
[1.0.3]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.2...v1.0.3
[1.0.2]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/Chia-Mine/clvm-js/compare/v1.0.0...v1.0.1
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.3",
"version": "1.0.4",
"author": "Admin ChiaMineJP <[email protected]>",
"description": "Javascript implementation of chia lisp",
"license": "MIT",
Expand Down
10 changes: 5 additions & 5 deletions src/SExp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ export function convert_atom_to_bytes(v: any): Bytes {
return Bytes.from(v, "utf8");
}
else if(typeof v === "number"){
return int_to_bytes(v);
return int_to_bytes(v, {signed: true});
}
else if(typeof v === "boolean"){ // Tips. In Python, isinstance(True, int) == True.
return int_to_bytes(v ? 1 : 0);
return int_to_bytes(v ? 1 : 0, {signed: true});
}
else if(typeof v === "bigint"){
return bigint_to_bytes(v);
return bigint_to_bytes(v, {signed: true});
}
else if(v === None || !v){
return Bytes.NULL;
Expand Down Expand Up @@ -218,11 +218,11 @@ export class SExp implements CLVMType {
}

public as_int(){
return int_from_bytes(this.atom);
return int_from_bytes(this.atom, {signed: true});
}

public as_bigint(){
return bigint_from_bytes(this.atom);
return bigint_from_bytes(this.atom, {signed: true});
}

public as_bin(){
Expand Down
35 changes: 25 additions & 10 deletions src/casts.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,62 @@
import {None} from "./__python_types__";
import {Bytes} from "./__type_compatibility__";

export function int_from_bytes(b: Bytes|None): number {
export type TConvertOption = {
signed: boolean;
};

export function int_from_bytes(b: Bytes|None, option?: Partial<TConvertOption>): number {
if(!b || b.length === 0){
return 0;
}
else if(b.length*8 > 52){
throw new Error("Cannot convert Bytes to Integer larger than 52bit. Use bigint_from_bytes instead.");
}
const signed = (option && typeof option.signed === "boolean") ? option.signed : false;
let unsigned32 = 0;
for(let i=b.length-1;i>=0;i--){
const byte = b.at(i);
unsigned32 += byte * (256**((b.length-1)-i));
}
// If the first bit is 1, it is recognized as a negative number.
if(b.at(0) & 0x80){
if(signed && (b.at(0) & 0x80)){
return unsigned32 - (256**b.length);
}
return unsigned32;
}

export function bigint_from_bytes(b: Bytes|None): bigint {
export function bigint_from_bytes(b: Bytes|None, option?: Partial<TConvertOption>): bigint {
if(!b || b.length === 0){
return BigInt(0);
}
const signed = (option && typeof option.signed === "boolean") ? option.signed : false;
let unsigned32 = BigInt(0);
for(let i=b.length-1;i>=0;i--){
const byte = b.at(i);
unsigned32 += BigInt(byte) * (BigInt(256)**(BigInt((b.length-1)-i)));
}
// If the first bit is 1, it is recognized as a negative number.
if(b.at(0) & 0x80){
if(signed && (b.at(0) & 0x80)){
return unsigned32 - (BigInt(1) << BigInt(b.length*8));
}
return unsigned32;
}

export function int_to_bytes(v: number): Bytes {
export function int_to_bytes(v: number, option?: Partial<TConvertOption>): Bytes {
if(v > Number.MAX_SAFE_INTEGER || v < Number.MIN_SAFE_INTEGER){
throw new Error(`The int value is beyond ${v > 0 ? "MAX_SAFE_INTEGER" : "MIN_SAFE_INTEGER"}: ${v}`);
}
if(v === 0){
return Bytes.NULL;
}

const signed = (option && typeof option.signed === "boolean") ? option.signed : false;
if(!signed && v < 0){
throw new Error("OverflowError: can't convert negative int to unsigned");
}
let byte_count = 1;
if(v > 0){
while(2**(8*byte_count - 1) - 1 < v){
while(2**(8*byte_count - (signed ? 1 : 0)) - 1 < v){
byte_count++;
}
}
Expand All @@ -56,7 +66,7 @@ export function int_to_bytes(v: number): Bytes {
}
}

const needExtraByte = v > 0 && ((v >> ((byte_count-1)*8)) & 0x80) > 0;
const needExtraByte = signed && v > 0 && ((v >> ((byte_count-1)*8)) & 0x80) > 0;
const u8 = new Uint8Array(byte_count+(needExtraByte ? 1 : 0));
for(let i=0;i<byte_count;i++){
const j = needExtraByte ? i+1 : i;
Expand All @@ -66,13 +76,18 @@ export function int_to_bytes(v: number): Bytes {
return new Bytes(u8);
}

export function bigint_to_bytes(v: bigint): Bytes {
export function bigint_to_bytes(v: bigint, option?: Partial<TConvertOption>): Bytes {
if(v === BigInt(0)){
return Bytes.NULL;
}

const signed = (option && typeof option.signed === "boolean") ? option.signed : false;
if(!signed && v < BigInt(0)){
throw new Error("OverflowError: can't convert negative int to unsigned");
}
let byte_count = 1;
if(v > 0){
while(BigInt(2)**(BigInt(8)*BigInt(byte_count) - BigInt(1)) - BigInt(1) < v){
while(BigInt(2)**(BigInt(8)*BigInt(byte_count) - (signed ? BigInt(1) : BigInt(0))) - BigInt(1) < v){
byte_count++;
}
}
Expand All @@ -82,7 +97,7 @@ export function bigint_to_bytes(v: bigint): Bytes {
}
}

const needExtraByte = v > 0 && ((v >> (BigInt(byte_count-1)*BigInt(8))) & BigInt(0x80)) > BigInt(0);
const needExtraByte = signed && v > 0 && ((v >> (BigInt(byte_count-1)*BigInt(8))) & BigInt(0x80)) > BigInt(0);
const u8 = new Uint8Array(byte_count+(needExtraByte ? 1 : 0));
for(let i=0;i<byte_count;i++){
const j = needExtraByte ? i+1 : i;
Expand Down
4 changes: 2 additions & 2 deletions src/more_ops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export function op_pubkey_for_exp(args: SExp){
i0 = modulo(i0, BigInt("0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001")); // i0 % BigInt("0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001")
const {PrivateKey} = getBLSModule();
const bytes = new Uint8Array(32);
const u0 =bigint_to_bytes(i0).raw();
const u0 =bigint_to_bytes(i0, {signed: false}).raw();
if(u0.length > 0){
bytes.set(u0, 32 - u0.length);
}
Expand Down Expand Up @@ -376,7 +376,7 @@ export function op_lsh(args: SExp){
}
// we actually want i0 to be an *unsigned* int
const a0 = args.first().atom;
const i0 = bigint_from_bytes(a0);
const i0 = bigint_from_bytes(a0, {signed: false});
let r;
if(i1 >= 0){
r = i0 << i1;
Expand Down
2 changes: 1 addition & 1 deletion src/operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export function default_unknown_op(op: Bytes, args: SExp): Tuple<number, CLVMObj
}

// The bytes here is 4bytes or smaller. So `int_from_bytes` is enough. (No bigint_from_bytes required)
const cost_multiplier = int_from_bytes(op.subarray(0, op.length-1)) + 1;
const cost_multiplier = int_from_bytes(op.subarray(0, op.length-1), {signed: false}) + 1;
/*
# 0 = constant
# 1 = like op_add/op_sub
Expand Down
Loading

0 comments on commit 8fbe3fd

Please sign in to comment.