Skip to content

Commit

Permalink
Merge branch '34-add-getguardspkconfig-to-ergochain' into 'dev'
Browse files Browse the repository at this point in the history
add pk extractor Ergo, add Cardano native asset variable

Closes #34

See merge request ergo/rosen-bridge/rosen-chains!34
  • Loading branch information
vorujack committed Jun 27, 2023
2 parents 75c215d + 2320890 commit a46e8e3
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 19 deletions.
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/chains/cardano/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs';

const CARDANO_CHAIN = 'cardano';
const ADA = 'ada';

const protocolParameters = {
minFeeA: CardanoWasm.BigNum.from_str('44'),
Expand All @@ -27,4 +28,4 @@ const txBuilderConfig: CardanoWasm.TransactionBuilderConfig =
.coins_per_utxo_word(protocolParameters.coinsPerUtxoWord)
.build();

export { txBuilderConfig, CARDANO_CHAIN };
export { txBuilderConfig, CARDANO_CHAIN, ADA };
2 changes: 1 addition & 1 deletion packages/chains/cardano/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rosen-chains/cardano",
"version": "0.1.8",
"version": "0.1.9",
"description": "this project contains cardano chain for Rosen-bridge",
"main": "dist/lib/index.js",
"types": "dist/lib/index.d.ts",
Expand Down
50 changes: 49 additions & 1 deletion packages/chains/ergo/lib/ErgoChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import * as wasm from 'ergo-lib-wasm-nodejs';
import Serializer from './Serializer';
import { blake2b } from 'blakejs';
import { ERGO_CHAIN } from './constants';
import { ErgoConfigs } from './types';
import { ErgoConfigs, GuardsPkConfig } from './types';
import { AbstractLogger } from '@rosen-bridge/logger-interface';
import ErgoTransaction from './ErgoTransaction';
import ErgoUtils from './ErgoUtils';
Expand Down Expand Up @@ -856,6 +856,54 @@ class ErgoChain extends AbstractUtxoChain<wasm.ErgoBox> {
eventBox.tokens().get(0).id().to_str() === expectedRWT
);
};

/**
* gets guards public keys and required signs from config box in the blockchain
* @param guardNFT the guard NFT tokenId
* @param address address containing guard config box
*/
getGuardsPkConfig = async (
guardNFT: string,
address: string
): Promise<GuardsPkConfig> => {
const guardBox = wasm.ErgoBox.sigma_parse_bytes(
Buffer.from(await this.getGuardsConfigBox(guardNFT, address), 'hex')
);
try {
const r4 = guardBox.register_value(4)?.to_coll_coll_byte();
const r5 = guardBox.register_value(5)?.to_i32_array();

if (r4 === undefined || r5 === undefined)
throw Error(`R4 or R5 is empty`);

return {
publicKeys: r4.map((pk) => Buffer.from(pk).toString('hex')),
requiredSigns: r5[0],
};
} catch (e) {
this.logger.debug(
`Cannot get guards pk config from box [${guardBox
.box_id()
.to_str()}]. R4 [${guardBox
.register_value(4)
?.encode_to_base16()}], R5 [${guardBox
.register_value(5)
?.encode_to_base16()}]`
);
throw Error(
`Failed to get guards public keys from box [${guardBox
.box_id()
.to_str()}] due to invalid registers: ${e}`
);
}
};

/**
* gets the context of blockchain using 10 last blocks
* @returns the state context object
*/
getStateContext = async (): Promise<wasm.ErgoStateContext> =>
await this.network.getStateContext();
}

export default ErgoChain;
7 changes: 6 additions & 1 deletion packages/chains/ergo/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ interface ErgoTransactionJsonModel extends PaymentTransactionJsonModel {
dataInputs: Array<string>;
}

export { ErgoConfigs, ErgoTransactionJsonModel };
interface GuardsPkConfig {
publicKeys: Array<string>;
requiredSigns: number;
}

export { ErgoConfigs, ErgoTransactionJsonModel, GuardsPkConfig };
2 changes: 1 addition & 1 deletion packages/chains/ergo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rosen-chains/ergo",
"version": "0.1.13",
"version": "0.1.14",
"description": "this project contains ergo chain for Rosen-bridge",
"main": "dist/lib/index.js",
"types": "dist/lib/index.d.ts",
Expand Down
71 changes: 71 additions & 0 deletions packages/chains/ergo/tests/ErgoChain.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2221,4 +2221,75 @@ describe('ErgoChain', () => {
expect(result).toEqual(false);
});
});

describe('getGuardsPkConfig', () => {
/**
* @target ErgoChain.getGuardsPkConfig should get guards public key config successfully
* @dependencies
* @scenario
* - mock guard config box and guardNFT
* - mock a network object with mocked 'getBoxesByTokenId'
* - run test
* - check returned value
* @expected
* - it should return expected public keys and requiredSigns
*/
it('should get guards public key config successfully', async () => {
// mock guard config box and guardNFT
const box = ergoTestUtils.toErgoBox(boxTestData.guardConfigBox);
const guardNFT = boxTestData.guardNFT;

// mock a network object
const network = new TestErgoNetwork();
// mock 'getBoxesByTokenId'
const getBoxesByTokenIdSpy = spyOn(network, 'getBoxesByTokenId');
when(getBoxesByTokenIdSpy)
.calledWith(guardNFT, ergoTestUtils.testLockAddress)
.mockResolvedValue([box]);

// run test
const ergoChain = generateChainObject(network);
const result = await ergoChain.getGuardsPkConfig(
guardNFT,
ergoTestUtils.testLockAddress
);

// check returned value
expect(result).toEqual(boxTestData.guardPks);
});

/**
* @target ErgoChain.getGuardsPkConfig should throw error when
* register values are invalid
* @dependencies
* @scenario
* - mock an invalid box and guardNFT
* - mock a network object with mocked 'getBoxesByTokenId'
* - run test and expect exception thrown
* @expected
* - it should throw Error
*/
it('should throw error when register values are invalid', async () => {
// mock an invalid box and guardNFT
const box = ergoTestUtils.toErgoBox(boxTestData.eventBox1);
const guardNFT = boxTestData.guardNFT;

// mock a network object
const network = new TestErgoNetwork();
// mock 'getBoxesByTokenId'
const getBoxesByTokenIdSpy = spyOn(network, 'getBoxesByTokenId');
when(getBoxesByTokenIdSpy)
.calledWith(guardNFT, ergoTestUtils.testLockAddress)
.mockResolvedValue([box]);

// run test and expect exception thrown
const ergoChain = generateChainObject(network);
await expect(async () => {
await ergoChain.getGuardsPkConfig(
guardNFT,
ergoTestUtils.testLockAddress
);
}).rejects.toThrow(Error);
});
});
});
37 changes: 37 additions & 0 deletions packages/chains/ergo/tests/boxTestData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AssetBalance, EventTrigger } from '@rosen-chains/abstract-chain';
import { GuardsPkConfig } from '../lib';

export const ergoBox1 = `{
"boxId": "09704ca5e07fe502e4974b07ba8ec7e32c242d1dfc06b036465d6596f5a8ed4b",
Expand Down Expand Up @@ -156,6 +157,42 @@ export const box1Assets: AssetBalance = {
],
};

export const guardConfigBox = `{
"boxId": "6eccf30dc9e6d40e20f8dddc3d66e7ee45c82216906a2bacf14be9da8a811309",
"value": 1100000,
"ergoTree": "100504000400040004000402d802d601c2a7d602b2a5730000ea02d196830301937201c2b2a473010093c272027201938cb2db63087202730200018cb2db6308a77303000198b2e4c6a70510730400ade4c6a7041ad901030ecdee7203",
"assets": [
{
"tokenId": "b039e4445337697deaad703fc8d1fcb129c4577e8673394fa2403e54d484eeda",
"amount": 1
}
],
"additionalRegisters": {
"R4": "1a0a2103c236922914cf80be4b642b3ea02f532ceb120a82b7bc5b75a8c2b7dc70810a272102b1d6b33c5ef442fa140d52352cab3e80780e98a44bcf6826604f100dbe2cbec8210217b8b16c47f83c6e96324f4d65434cd77aca1ab969878ba8293b87001c4f216f21024df46a0f95903d15cc8c4f390bb3d0f97dee85273591a88575206baf2d54812e2103aa26adb6a56132f52c0919a351b738beee0d2a240d6b5a82eff27a0f662f34592102d64bd38b103af945c5786dfbd63577779f49e7166e69f622dc5c243dcbbdbab921024f0556828a51b54a2b17bf9d4cc4c7fd9faa3226513193ae0aeaf9075bad4aca2102a8b0cc627e16301030b1a74fc33d49dd364a2b818d5d25e02b4d9e3bfc1f4aac2103380c129ffb41ccc52dd58a128082ac381bb449ef67d230255eea28425599852421023605f5625c0f1099c5966a58a9291d7a546d432faeb99d88a99fa6b745b1fd31",
"R5": "10020e10"
},
"creationHeight": 969636,
"transactionId": "2d6baff61607166b03da7c68eec2d3ea4611ff88cbf36d964f648f64f8c2cfb8",
"index": 0
}`;
export const guardNFT =
'b039e4445337697deaad703fc8d1fcb129c4577e8673394fa2403e54d484eeda';
export const guardPks: GuardsPkConfig = {
publicKeys: [
'03c236922914cf80be4b642b3ea02f532ceb120a82b7bc5b75a8c2b7dc70810a27',
'02b1d6b33c5ef442fa140d52352cab3e80780e98a44bcf6826604f100dbe2cbec8',
'0217b8b16c47f83c6e96324f4d65434cd77aca1ab969878ba8293b87001c4f216f',
'024df46a0f95903d15cc8c4f390bb3d0f97dee85273591a88575206baf2d54812e',
'03aa26adb6a56132f52c0919a351b738beee0d2a240d6b5a82eff27a0f662f3459',
'02d64bd38b103af945c5786dfbd63577779f49e7166e69f622dc5c243dcbbdbab9',
'024f0556828a51b54a2b17bf9d4cc4c7fd9faa3226513193ae0aeaf9075bad4aca',
'02a8b0cc627e16301030b1a74fc33d49dd364a2b818d5d25e02b4d9e3bfc1f4aac',
'03380c129ffb41ccc52dd58a128082ac381bb449ef67d230255eea284255998524',
'023605f5625c0f1099c5966a58a9291d7a546d432faeb99d88a99fa6b745b1fd31',
],
requiredSigns: 7,
};

export const validEvent: EventTrigger = {
height: 200,
fromChain: 'ergo',
Expand Down
4 changes: 2 additions & 2 deletions packages/networks/cardano-koios/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rosen-chains/cardano-koios-network",
"version": "0.1.5",
"version": "0.1.6",
"description": "cardano koios network package for rosen cardano chain",
"main": "dist/lib/index.js",
"types": "dist/lib/index.d.ts",
Expand All @@ -25,7 +25,7 @@
"@rosen-bridge/rosen-extractor": "^0.1.8",
"@rosen-bridge/tokens": "^0.1.12",
"@rosen-chains/abstract-chain": "^0.1.10",
"@rosen-chains/cardano": "^0.1.8",
"@rosen-chains/cardano": "^0.1.9",
"@rosen-clients/cardano-koios": "^0.2.2",
"json-bigint": "^1.0.0"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/networks/ergo-explorer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rosen-chains/ergo-explorer-network",
"version": "0.1.8",
"version": "0.1.9",
"description": "ergo explorer network package for rosen ergo chain",
"main": "dist/lib/index.js",
"types": "dist/lib/index.d.ts",
Expand All @@ -24,7 +24,7 @@
"@rosen-bridge/rosen-extractor": "^0.1.8",
"@rosen-bridge/tokens": "^0.1.12",
"@rosen-chains/abstract-chain": "^0.1.10",
"@rosen-chains/ergo": "^0.1.13",
"@rosen-chains/ergo": "^0.1.14",
"@rosen-clients/ergo-explorer": "^0.3.0",
"ergo-lib-wasm-nodejs": "^0.23.0",
"it-all": "^3.0.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/networks/ergo-node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rosen-chains/ergo-node-network",
"version": "0.1.10",
"version": "0.1.11",
"description": "ergo node network package for rosen ergo chain",
"main": "dist/lib/index.js",
"types": "dist/lib/index.d.ts",
Expand All @@ -24,7 +24,7 @@
"@rosen-bridge/rosen-extractor": "^0.1.8",
"@rosen-bridge/tokens": "^0.1.12",
"@rosen-chains/abstract-chain": "^0.1.10",
"@rosen-chains/ergo": "^0.1.13",
"@rosen-chains/ergo": "^0.1.14",
"@rosen-clients/ergo-node": "^0.3.2",
"ergo-lib-wasm-nodejs": "^0.23.0",
"it-all": "^3.0.1",
Expand Down

0 comments on commit a46e8e3

Please sign in to comment.