Skip to content

Commit

Permalink
Merge branch 'Add-TriggerTxBuilder.createTriggerBox' into 'dev'
Browse files Browse the repository at this point in the history
implement TriggerTxBuilder.createTriggerBox

Closes #177

See merge request ergo/rosen-bridge/watcher!175
  • Loading branch information
vorujack committed Dec 1, 2023
2 parents 58d5a0a + 7fafb5d commit facff2b
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 6 deletions.
105 changes: 100 additions & 5 deletions packages/transactions/trigger/lib/triggerTxBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { AbstractLogger } from '@rosen-bridge/abstract-logger';
import { AbstractLogger, DummyLogger } from '@rosen-bridge/abstract-logger';
import { ObservationEntity } from '@rosen-bridge/observation-extractor';
import { RWTRepo } from '@rosen-bridge/rwt-repo';
import { blake2b } from 'blakejs';
import * as ergoLib from 'ergo-lib-wasm-nodejs';
import { bigIntToUint8Array, toScriptHash, uint8ArrayToHex } from './utils';
import {
bigIntToUint8Array,
hexToUint8Array,
toScriptHash,
uint8ArrayToHex,
} from './utils';

export class TriggerTxBuilder {
private permitScriptHash: string;
Expand All @@ -21,7 +26,7 @@ export class TriggerTxBuilder {
private txFee: string,
private rwtRepo: RWTRepo,
private observation: ObservationEntity,
private logger?: AbstractLogger
private logger: AbstractLogger = new DummyLogger()
) {
this.permitScriptHash = toScriptHash(permitAddress);
}
Expand All @@ -37,7 +42,7 @@ export class TriggerTxBuilder {
throw new Error('creation height must be a positive integer');
}
this.creationHeight = height;
this.logger?.debug(`new value set for height=[${this.creationHeight}]`);
this.logger.debug(`new value set for height=[${this.creationHeight}]`);
return this;
};

Expand Down Expand Up @@ -79,7 +84,7 @@ export class TriggerTxBuilder {
}
this.commitments.push(...validCommitments);
this.wids.push(...validWids);
this.logger?.debug(
this.logger.debug(
`added new commitments with boxIds=[${validCommitments
.map((commitment) => commitment.box_id().to_str())
.join(', ')}] and wids=[${this.wids.join(
Expand Down Expand Up @@ -196,4 +201,94 @@ export class TriggerTxBuilder {
]);
return blake2b(content, undefined, 32);
};

/**
* creates the trigger box
*
* @param {bigint} rwtCount
* @param {bigint} value
* @return {ergoLib.ErgoBoxCandidate}
*/
private createTriggerBox = (
rwtCount: bigint,
value: bigint
): ergoLib.ErgoBoxCandidate => {
const boxBuilder = new ergoLib.ErgoBoxCandidateBuilder(
ergoLib.BoxValue.from_i64(ergoLib.I64.from_str(value.toString())),
ergoLib.Contract.pay_to_address(
ergoLib.Address.from_base58(this.triggerAddress)
),
this.creationHeight
);

boxBuilder.add_token(
ergoLib.TokenId.from_str(this.rwt),
ergoLib.TokenAmount.from_i64(ergoLib.I64.from_str(rwtCount.toString()))
);
this.logger.debug(
`added rwt tokens to trigger box with amount=[${rwtCount}]`
);

boxBuilder.set_register_value(
4,
ergoLib.Constant.from_coll_coll_byte(
this.wids.map((wid) => hexToUint8Array(wid))
)
);
this.logger.debug(
`added wids to R4 register of trigger box: wids=[${this.wids}]`
);

boxBuilder.set_register_value(
5,
ergoLib.Constant.from_coll_coll_byte(this.eventData)
);
this.logger.debug(
`added event data to R5 register of trigger box: event-data=[${this.rawEventData}]`
);

boxBuilder.set_register_value(
6,
ergoLib.Constant.from_byte_array(hexToUint8Array(this.permitScriptHash))
);
this.logger.debug(
`added permit script hash to R6 register of trigger box: permit-script-hash=[${this.permitScriptHash}]`
);

return boxBuilder.build();
};

private get eventData() {
return [
Buffer.from(this.observation.sourceTxId),
Buffer.from(this.observation.fromChain),
Buffer.from(this.observation.toChain),
Buffer.from(this.observation.fromAddress),
Buffer.from(this.observation.toAddress),
bigIntToUint8Array(BigInt(this.observation.amount)),
bigIntToUint8Array(BigInt(this.observation.bridgeFee)),
bigIntToUint8Array(BigInt(this.observation.networkFee)),
Buffer.from(this.observation.sourceChainTokenId),
Buffer.from(this.observation.targetChainTokenId),
Buffer.from(this.observation.sourceBlockId),
bigIntToUint8Array(BigInt(this.observation.height)),
];
}

private get rawEventData() {
return [
this.observation.sourceTxId,
this.observation.fromChain,
this.observation.toChain,
this.observation.fromAddress,
this.observation.toAddress,
this.observation.amount,
this.observation.bridgeFee,
this.observation.networkFee,
this.observation.sourceChainTokenId,
this.observation.targetChainTokenId,
this.observation.sourceBlockId,
this.observation.height,
];
}
}
62 changes: 61 additions & 1 deletion packages/transactions/trigger/tests/triggerTxBuilder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import JsonBigInt from '@rosen-bridge/json-bigint';
import * as ergoLib from 'ergo-lib-wasm-nodejs';
import { beforeEach, describe, expect, it } from 'vitest';
import { TriggerTxBuilder } from '../lib';
import { hexToUint8Array, uint8ArrayToHex } from '../lib/utils';
import {
createCommitmentErgoBox,
sampleCommitmentBoxes,
Expand All @@ -13,7 +14,6 @@ import {
sampleRwtRepoboxInfo,
triggerTxParams,
} from './triggerTxTestData';
import { hexToUint8Array } from '../lib/utils';

describe('TriggerTxBuilder', () => {
let triggerTxBuilder: TriggerTxBuilder;
Expand Down Expand Up @@ -312,4 +312,64 @@ describe('TriggerTxBuilder', () => {
);
});
});

describe('createTriggerBox', () => {
/**
* @target should create a trigger box from instance's properties
* @dependencies
* @scenario
* - setup triggerTxBuilder instance
* - call createTriggerBox
* - check returned box to have the right properties set
* @expected
* - returned box should have the right properties set
*/
it(`should create a trigger box from instance's properties`, async () => {
const height = 100;
triggerTxBuilder.setCreationHeight(height);

const commitments = sampleCommitmentBoxes
.slice(0, 3)
.map((boxInfo) =>
ergoLib.ErgoBox.from_json(JsonBigInt.stringify(boxInfo))
);

triggerTxBuilder.addCommitments(commitments);

const rsnValue =
BigInt(triggerTxBuilder['wids'].length) *
triggerTxBuilder['rwtRepo'].getCommitmentRwtCount();
const value = 10_000_000_000n;
const triggerBox = triggerTxBuilder['createTriggerBox'](rsnValue, value);

expect(triggerBox.value().as_i64().to_str()).toEqual(value.toString());

expect(
ergoLib.Address.recreate_from_ergo_tree(
triggerBox.ergo_tree()
).to_base58(ergoLib.NetworkPrefix.Mainnet)
).toEqual(triggerTxBuilder['triggerAddress']);

expect(triggerBox.creation_height()).toEqual(height);

expect(triggerBox.tokens().get(0).id().to_str()).toEqual(
triggerTxBuilder['rwt']
);
expect(triggerBox.tokens().get(0).amount().as_i64().to_str()).toEqual(
rsnValue.toString()
);

expect(triggerBox.register_value(4)?.to_coll_coll_byte()).toEqual(
triggerTxBuilder['wids'].map((wid) => hexToUint8Array(wid))
);

expect(triggerBox.register_value(5)!.to_coll_coll_byte()).toEqual(
triggerTxBuilder['eventData'].map((data) => new Uint8Array(data))
);

expect(
uint8ArrayToHex(triggerBox.register_value(6)!.to_byte_array())
).toEqual(triggerTxBuilder['permitScriptHash']);
});
});
});

0 comments on commit facff2b

Please sign in to comment.