Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix minor bugs #389

Merged
merged 4 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .project.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"infos": {
"Add": {
"sourceFile": "add/add.ral",
"sourceCodeHash": "b3a4696a12e8cbb2cb5fb1ebe18000beb0e67e9ff7194300b01f9cff8862701c",
"bytecodeDebugPatch": "=12-2+5a=3-1+f=2-2+ac=2+b=1-1=83+77e010a=1+1646450726976617465=262",
"codeHashDebug": "34b2d26e23a53fafc6d898ca4911f50ebc782e3d2836af0f235f2e18c6875dd3",
"sourceCodeHash": "e53e74ff98c352525e856abd4311868176d45c61c957791c3d42eae274088df0",
"bytecodeDebugPatch": "=12-2+5c=2-2+81=3-1+e=2-2+bc=83-1+97e010a61646450726976617465=266",
"codeHashDebug": "c46db1ae7bae8b332c115869126eb1402bc71574925608a2adcea3cf7b9f8e7e",
"warnings": [
"Found unused variables in Add: add2.addS, add2.address, add2.array2",
"The return values of the function \"Add.copyCreateSubContract\" are not used. If this is intentional, consider using anonymous variables to suppress this warning.",
Expand All @@ -26,7 +26,7 @@
},
"AddMain": {
"sourceFile": "add/add.ral",
"sourceCodeHash": "b3a4696a12e8cbb2cb5fb1ebe18000beb0e67e9ff7194300b01f9cff8862701c",
"sourceCodeHash": "e53e74ff98c352525e856abd4311868176d45c61c957791c3d42eae274088df0",
"bytecodeDebugPatch": "",
"codeHashDebug": "",
"warnings": [
Expand All @@ -35,14 +35,14 @@
},
"AddStruct1": {
"sourceFile": "add/add.ral",
"sourceCodeHash": "b3a4696a12e8cbb2cb5fb1ebe18000beb0e67e9ff7194300b01f9cff8862701c",
"sourceCodeHash": "e53e74ff98c352525e856abd4311868176d45c61c957791c3d42eae274088df0",
"bytecodeDebugPatch": "",
"codeHashDebug": "",
"warnings": []
},
"AddStruct2": {
"sourceFile": "add/add.ral",
"sourceCodeHash": "b3a4696a12e8cbb2cb5fb1ebe18000beb0e67e9ff7194300b01f9cff8862701c",
"sourceCodeHash": "e53e74ff98c352525e856abd4311868176d45c61c957791c3d42eae274088df0",
"bytecodeDebugPatch": "",
"codeHashDebug": "",
"warnings": []
Expand Down
29 changes: 8 additions & 21 deletions artifacts/add/Add.ral.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"version": "v2.14.7",
"version": "v3.2.0",
"name": "Add",
"bytecode": "0206124024404d4072409f40ad010002100205d34fbb20db1600160100020201000c0c0205d36a51f82d1600160100020200000202021605160016015f06160016015fa00016002a16012aa100a000160016010e0dce000100020103040c0011d319adf50e1300641600130164170517041603d1a21601160216041605c118010104060015d3f6ce55a6130064160013016417051704160316021340c8ac1603d1a21601160216041605c118010201010003d320f98f621600b0",
"codeHash": "eb94a22e8e2600075ff538c6e79cb46e7a8d4fae5c29eee9f5afd7fabd26426b",
"bytecode": "0206124024404f407440a140af010002100205d34fbb20db1600160100020201000c0c0205d36a51f82d1600160100020200000202021805160016015f06160016015f075da00016002a16012aa100a000160016010e0dce000100020103040c0011d319adf50e1300641600130164170517041603d1a21601160216041605c118010104060015d3f6ce55a6130064160013016417051704160316021340c8ac1603d1a21601160216041605c118010201010003d320f98f621600b0",
"codeHash": "6a1f1415a68d55365e205b39e5418cd1f6fc8c2c7926d3662c77d69b55c92681",
"fieldsSig": {
"names": [
"sub",
Expand Down Expand Up @@ -39,14 +39,16 @@
"U256",
"U256"
]
},
{
"name": "Empty",
"fieldNames": [],
"fieldTypes": []
}
],
"functions": [
{
"name": "add",
"usePreapprovedAssets": false,
"useAssetsInContract": false,
"isPublic": true,
"paramNames": [
"array"
],
Expand All @@ -62,9 +64,6 @@
},
{
"name": "add2",
"usePreapprovedAssets": false,
"useAssetsInContract": false,
"isPublic": true,
"paramNames": [
"array1",
"address",
Expand All @@ -89,9 +88,6 @@
},
{
"name": "addPrivate",
"usePreapprovedAssets": false,
"useAssetsInContract": false,
"isPublic": false,
"paramNames": [
"array"
],
Expand All @@ -107,9 +103,6 @@
},
{
"name": "createSubContract",
"usePreapprovedAssets": true,
"useAssetsInContract": false,
"isPublic": true,
"paramNames": [
"a",
"path",
Expand All @@ -132,9 +125,6 @@
},
{
"name": "createSubContractAndTransfer",
"usePreapprovedAssets": true,
"useAssetsInContract": true,
"isPublic": true,
"paramNames": [
"a",
"path",
Expand All @@ -157,9 +147,6 @@
},
{
"name": "destroy",
"usePreapprovedAssets": false,
"useAssetsInContract": true,
"isPublic": true,
"paramNames": [
"caller"
],
Expand Down
5 changes: 1 addition & 4 deletions artifacts/add/AddMain.ral.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v2.14.7",
"version": "v3.2.0",
"name": "AddMain",
"bytecodeTemplate": "0101030002000c{1}{2}17011700160016010e0e{0}01001818",
"fieldsSig": {
Expand All @@ -19,9 +19,6 @@
"functions": [
{
"name": "main",
"usePreapprovedAssets": true,
"useAssetsInContract": false,
"isPublic": true,
"paramNames": [],
"paramTypes": [],
"paramIsMutable": [],
Expand Down
24 changes: 20 additions & 4 deletions artifacts/ts/Add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export namespace AddTypes {

export type AddEvent = ContractEvent<{ x: bigint; y: bigint }>;
export type Add1Event = ContractEvent<{ a: bigint; b: bigint }>;
export type EmptyEvent = ContractEvent<{}>;

export interface CallMethodTable {
add: {
Expand Down Expand Up @@ -160,7 +161,7 @@ class Factory extends ContractFactory<AddInstance, AddTypes.Fields> {
return this.contract.getInitialFieldsWithDefaultValues() as AddTypes.Fields;
}

eventIndex = { Add: 0, Add1: 1 };
eventIndex = { Add: 0, Add1: 1, Empty: 2 };

at(address: string): AddInstance {
return new AddInstance(address);
Expand Down Expand Up @@ -237,8 +238,8 @@ class Factory extends ContractFactory<AddInstance, AddTypes.Fields> {
export const Add = new Factory(
Contract.fromJson(
AddContractJson,
"=12-2+5a=3-1+f=2-2+ac=2+b=1-1=83+77e010a=1+1646450726976617465=262",
"34b2d26e23a53fafc6d898ca4911f50ebc782e3d2836af0f235f2e18c6875dd3",
"=12-2+5c=2-2+81=3-1+e=2-2+bc=83-1+97e010a61646450726976617465=266",
"c46db1ae7bae8b332c115869126eb1402bc71574925608a2adcea3cf7b9f8e7e",
AllStructs
)
);
Expand Down Expand Up @@ -283,8 +284,23 @@ export class AddInstance extends ContractInstance {
);
}

subscribeEmptyEvent(
options: EventSubscribeOptions<AddTypes.EmptyEvent>,
fromCount?: number
): EventSubscription {
return subscribeContractEvent(
Add.contract,
this,
options,
"Empty",
fromCount
);
}

subscribeAllEvents(
options: EventSubscribeOptions<AddTypes.AddEvent | AddTypes.Add1Event>,
options: EventSubscribeOptions<
AddTypes.AddEvent | AddTypes.Add1Event | AddTypes.EmptyEvent
>,
fromCount?: number
): EventSubscription {
return subscribeContractEvents(Add.contract, this, options, fromCount);
Expand Down
2 changes: 2 additions & 0 deletions contracts/add/add.ral
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct AddStruct2 {
Contract Add(sub: Sub, mut result : U256) {
event Add(x: U256, y: U256)
event Add1(a: U256, b: U256)
event Empty()

pub fn add(array: [U256; 2]) -> ([U256; 2]) {
return addPrivate(array)
Expand All @@ -25,6 +26,7 @@ Contract Add(sub: Sub, mut result : U256) {
emit Debug(`addPrivate`)
emit Add(array[0], array[1])
emit Add1(array[0], array[1])
emit Empty()
result = result + array[0] + array[1]
return [result, sub.sub(array)]
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ function getEventType(event: EventSig): string {

function genEventType(event: EventSig): string {
if (event.fieldNames.length === 0) {
return `export type ${getEventType(event)} = Omit<ContractEvent, 'fields'>`
return `export type ${getEventType(event)} = ContractEvent<{}>`
}
const fieldsType = `{${formatParameters({ names: event.fieldNames, types: event.fieldTypes })}}`
return `export type ${getEventType(event)} = ContractEvent<${fieldsType}>`
Expand Down
31 changes: 31 additions & 0 deletions packages/web3-test/src/test-wallet.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.

The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { TOTAL_NUMBER_OF_GROUPS, groupOfAddress } from '@alephium/web3'
import { randomContractAddress } from './test-wallet'

describe('test-wallet', function () {
it('should generate random contract id by group index', () => {
for (let group = 0; group < TOTAL_NUMBER_OF_GROUPS; group += 1) {
const contractAddress = randomContractAddress(group)
expect(groupOfAddress(contractAddress)).toEqual(group)
}
expect(() => randomContractAddress(TOTAL_NUMBER_OF_GROUPS)).toThrow('Invalid group index')
expect(() => randomContractAddress(-1)).toThrow('Invalid group index')
})
})
13 changes: 8 additions & 5 deletions packages/web3-test/src/test-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import {
ALPH_TOKEN_ID,
DUST_AMOUNT,
Address,
TOTAL_NUMBER_OF_GROUPS
TOTAL_NUMBER_OF_GROUPS,
binToHex
} from '@alephium/web3'
import { NodeWallet, PrivateKeyWallet } from '@alephium/web3-wallet'
import { randomBytes } from 'crypto'
Expand Down Expand Up @@ -142,10 +143,12 @@ export async function expectAssertionError(
)
}

export function randomContractId(): string {
return randomBytes(32).toString('hex')
export function randomContractId(groupIndex = 0): string {
checkGroup(groupIndex)
const bytes = new Uint8Array([...randomBytes(31), groupIndex])
return binToHex(bytes)
}

export function randomContractAddress(): string {
return addressFromContractId(randomContractId())
export function randomContractAddress(groupIndex = 0): string {
return addressFromContractId(randomContractId(groupIndex))
}
1 change: 1 addition & 0 deletions packages/web3/src/address/address.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe('address', function () {
expect(() =>
validateAddress('2jVWAcAPphJ8ueZNG1BPwbfPFjjbvorprceuqzgmJQ1ZRyELRpWgARvdB3T9trqpiJs7f4GkudPt6rQLnGbQYqq2NCi')
).toThrow('Invalid multisig address, n: 2, m: 3')
expect(() => validateAddress('thebear')).toThrow('Invalid multisig address')
})

it('should get address type', () => {
Expand Down
13 changes: 13 additions & 0 deletions packages/web3/src/codec/codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,16 @@ export function assert(value: boolean, message: string) {
throw new Error(message)
}
}

export function fixedSizeBytes(name: string, length: number): Parser {
return Parser.start().wrapped({
length,
type: Parser.start().buffer(name, { length }),
wrapper: function (result) {
if (result.length === length) {
return result
}
throw new Error(`Too few bytes when parsing ${name}, expected ${length}, got ${result.length}`)
}
})
}
2 changes: 1 addition & 1 deletion packages/web3/src/codec/contract-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
import { Parser } from 'binary-parser'
import { ArrayCodec, DecodedArray } from './array-codec'
import { Codec } from './codec'
import { compactSignedIntCodec, compactUnsignedIntCodec, DecodedCompactInt } from './compact-int-codec'
import { compactSignedIntCodec, DecodedCompactInt } from './compact-int-codec'
import { Method, MethodCodec, methodCodec } from './method-codec'
import { concatBytes } from '../utils'

Expand Down
4 changes: 2 additions & 2 deletions packages/web3/src/codec/lockup-script-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
import { Parser } from 'binary-parser'
import { DecodedCompactInt, compactSignedIntCodec } from './compact-int-codec'
import { Codec } from './codec'
import { Codec, fixedSizeBytes } from './codec'
import { ArrayCodec, DecodedArray } from './array-codec'

export interface PublicKeyHash {
publicKeyHash: Uint8Array
}

class PublicKeyHashCodec implements Codec<PublicKeyHash> {
parser = Parser.start().buffer('publicKeyHash', { length: 32 })
parser = fixedSizeBytes('publicKeyHash', 32)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are encountering an issue with the binary-parser library, which causes the lockupScriptCodec.decode(hexToBinUnsafe('01ca40da2a3f')) function to return a run out of memory error:

  1. Because the prefix is 1, it attempts to decode P2MPKH.
  2. The decoded array size is huge. And even if from and to are out of the index, Uint8Array.subarray(from, to) does not throw an exception but returns an empty Uint8Array. Moreover, binary-parser does not check the length during runtime, leading to the allocation of a very large array and resulting in the out of memory error.

I feel like binary-parser lacks flexibility. It does not provide a direct way to check the size of the data. Currently it can only be checked through the wrapper.


encode(input: PublicKeyHash): Uint8Array {
return input.publicKeyHash
Expand Down
4 changes: 2 additions & 2 deletions packages/web3/src/codec/unlock-script-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
import { Parser } from 'binary-parser'
import { ArrayCodec, DecodedArray } from './array-codec'
import { compactUnsignedIntCodec, compactSignedIntCodec, DecodedCompactInt } from './compact-int-codec'
import { Codec } from './codec'
import { Codec, fixedSizeBytes } from './codec'
import { DecodedScript, scriptCodec } from './script-codec'
import { ByteString, byteStringCodec } from './bytestring-codec'
import { LockupScript, lockupScriptCodec } from './lockup-script-codec'
Expand All @@ -29,7 +29,7 @@ export interface P2PKH {
}

class P2PKHCodec implements Codec<P2PKH> {
parser = Parser.start().buffer('publicKey', { length: 33 })
parser = fixedSizeBytes('publicKey', 33)

encode(input: P2PKH): Uint8Array {
return input.publicKey
Expand Down
16 changes: 11 additions & 5 deletions test/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ describe('contract', function () {
it('should test event index', () => {
expect(Add.eventIndex.Add).toEqual(0)
expect(Add.eventIndex.Add1).toEqual(1)
expect(Add.eventIndex.Empty).toEqual(2)
expect(Sub.eventIndex.Sub).toEqual(0)
})

Expand Down Expand Up @@ -127,11 +128,16 @@ describe('contract', function () {
expect(event1.fields.a).toEqual(2n)
expect(event1.fields.b).toEqual(1n)

const event2 = events[2] as SubTypes.SubEvent
expect(event2.name).toEqual('Sub')
expect(event2.eventIndex).toEqual(0)
expect(event2.fields.x).toEqual(2n)
expect(event2.fields.y).toEqual(1n)
const event2 = events[2] as AddTypes.EmptyEvent
expect(event2.name).toEqual('Empty')
expect(event2.eventIndex).toEqual(2)
expect(event2.fields).toEqual({})

const event3 = events[3] as SubTypes.SubEvent
expect(event3.name).toEqual('Sub')
expect(event3.eventIndex).toEqual(0)
expect(event3.fields.x).toEqual(2n)
expect(event3.fields.y).toEqual(1n)
}

checkEvents(testResult.events)
Expand Down
Loading