Skip to main content

Defining a custom SplitStrategy

info

IOTA Owned Object Pools (IOTAOOP) is a beta library. Enhancements and changes are likely during development.

The prior example does not define a split strategy explicitly, so it uses the DefaultSplitStrategy.

This default split strategy only selects enough gas coins (coins of type 0x2::coin::Coin<0x2::iota::IOTA>) from the mainPool that their sum of balances surpasses a minimum threshold, and creates a new worker pool only containing these gas coins.

It fulfils the minimum requirement needed for a transaction to be executed, as the client should always be able to pay for the gas of the transaction.

However, in more complex scenarios, you might want to define your own split strategy.

Assume that you want to execute multiple transactions that transfer an object of type MyNFT, each to a different recipient.

For this to work, the ExecutorServiceHandler needs to split the mainPool in a way such that every worker:

  • Contains at least one MyNFT object.
  • Contains at least a coin (or set of coins) with a total balance enough to pay for the gas of the transaction.

To do this, you have to implement the SplitStrategy interface. In detail:

class MyCustomSplitStrategy implements SplitStrategy {
private myNftIncluded = false;
private balanceSoFar = 0;
private readonly minimumBalance;

public pred(obj: PoolObject | undefined) {
if (!obj) throw new Error('No object found!.');
// If each requirement is fulfilled then terminate the split by returning null
// This stops the split process and the worker pool is created
const terminateWhen = this.balanceSoFar >= this.minimumBalance && this.myNftIncluded;
if (terminateWhen) {
return null;
}
// If a MyNFT object is not already included, and the object is a MyNFT, then include it
if (!myNftIncluded && obj.type.includes('MyNFT')) {
this.myNftIncluded = true;
return true;
}
// If the object is a coin and coins are still needed, then include it to the new pool
if (this.balanceSoFar >= this.minimumBalance && isCoin(obj.type)) {
this.balanceSoFar += obj.balance ?? 0;
return true;
} else {
return false;
}
}
// This function is called during the split process to check if the split was successful
public succeeded() {
return this.balanceSoFar >= this.minimumBalance && this.adminCapIncluded;
}
}