Skip to content

Commit

Permalink
fix: injectNeededCapacity rare border capacity issue (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashuralyk authored Aug 21, 2024
1 parent 0a71917 commit 51f978c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
8 changes: 5 additions & 3 deletions packages/core/src/api/joints/spore/injectLiveSporeCell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ export async function injectLiveSporeCell(props: {
input: sporeCell,
addOutput: props.addOutput,
updateOutput(cell) {
if (props.capacityMargin !== void 0) {
cell = setAbsoluteCapacityMargin(cell, props.capacityMargin);
}
// May contain code about changing scripts, which causes the change of cell's occupied capacity,
// so here should be processed at first
if (props.updateOutput instanceof Function) {
cell = props.updateOutput(cell);
}
if (props.capacityMargin !== void 0) {
cell = setAbsoluteCapacityMargin(cell, props.capacityMargin);
}
return cell;
},
defaultWitness: props.defaultWitness,
Expand Down
25 changes: 12 additions & 13 deletions packages/core/src/helpers/capacity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,23 +170,23 @@ export function calculateNeededCapacity(props: {
let txSkeleton = props.txSkeleton;

const snapshot = createCapacitySnapshotFromTransactionSkeleton(txSkeleton);
const changeLock = helpers.parseAddress(props.changeAddress, { config: props.config });
// const changeLock = helpers.parseAddress(props.changeAddress, { config: props.config });

const extraCapacity = BI.from(props.extraCapacity ?? 0);
const minChangeCapacity = minimalCellCapacityByLock(changeLock).add(extraCapacity);
// const minChangeCapacity = minimalCellCapacityByLock(changeLock).add(extraCapacity);

let exceedCapacity = snapshot.inputsRemainCapacity;
let neededCapacity = snapshot.outputsRemainCapacity.add(extraCapacity);

// Collect one more cell if:
// 1. Has sufficient capacity for transaction construction
// 2. Has insufficient capacity for adding a change cell to Transaction.outputs
const sufficientForTransaction = neededCapacity.lte(0) && exceedCapacity.gt(0);
const insufficientForChangeCell = exceedCapacity.lt(minChangeCapacity);
if (sufficientForTransaction && insufficientForChangeCell) {
neededCapacity = minChangeCapacity;
exceedCapacity = BI.from(0);
}
// // Collect one more cell if:
// // 1. Has sufficient capacity for transaction construction
// // 2. Has insufficient capacity for adding a change cell to Transaction.outputs
// const sufficientForTransaction = neededCapacity.lte(0) && exceedCapacity.gt(0);
// const insufficientForChangeCell = exceedCapacity.lt(minChangeCapacity);
// if (sufficientForTransaction && insufficientForChangeCell) {
// neededCapacity = minChangeCapacity.sub(exceedCapacity);
// exceedCapacity = BI.from(0);
// }

if (neededCapacity.lt(0)) {
neededCapacity = BI.from(0);
Expand All @@ -213,7 +213,6 @@ export async function injectNeededCapacity(props: {
config?: Config;
extraCapacity?: BIish;
changeAddress?: Address;
enableDeductCapacity?: boolean;
}): Promise<{
txSkeleton: helpers.TransactionSkeletonType;
before: CapacitySnapshot;
Expand Down Expand Up @@ -244,7 +243,7 @@ export async function injectNeededCapacity(props: {
props.changeAddress,
void 0,
{
enableDeductCapacity: props.enableDeductCapacity,
enableDeductCapacity: true, // Set adding extra capacity to the last output cell as a default option
config: props.config,
},
);
Expand Down
17 changes: 15 additions & 2 deletions packages/core/src/helpers/fee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { Address, Transaction } from '@ckb-lumos/base';
import { BI, Header, helpers, RPC } from '@ckb-lumos/lumos';
import { BIish } from '@ckb-lumos/bi';
import { getSporeConfig, SporeConfig } from '../config';
import { injectNeededCapacity, returnExceededCapacity } from './capacity';
import { injectNeededCapacity, minimalCellCapacityByLock, returnExceededCapacity } from './capacity';
import { CapacitySnapshot, createCapacitySnapshotFromTransactionSkeleton } from './capacity';
import { getTransactionSize, getTransactionSkeletonSize } from './transaction';
import { fromInfoToAddress } from './address';

/**
* Get minimal acceptable fee rate from RPC.
Expand Down Expand Up @@ -154,7 +155,6 @@ export async function injectCapacityAndPayFee(props: {
feeRate?: BIish;
extraCapacity?: BIish;
changeAddress?: Address;
enableDeductCapacity?: boolean;
updateTxSkeletonAfterCollection?: (
txSkeleton: helpers.TransactionSkeletonType,
) => Promise<helpers.TransactionSkeletonType> | helpers.TransactionSkeletonType;
Expand All @@ -166,6 +166,19 @@ export async function injectCapacityAndPayFee(props: {
// Env
const config = props.config ?? getSporeConfig();

// Add a new change cell for receiving change capacity as default
const changeAddress = fromInfoToAddress(props.changeAddress ?? props.fromInfos[0], config.lumos);
const changeLock = helpers.addressToScript(changeAddress, { config: config.lumos });
props.txSkeleton = props.txSkeleton.update('outputs', (outputs) => {
return outputs.push({
cellOutput: {
capacity: minimalCellCapacityByLock(changeLock).toHexString(),
lock: changeLock,
},
data: '0x',
});
});

// Collect capacity
const injectNeededCapacityResult = await injectNeededCapacity({
...props,
Expand Down

0 comments on commit 51f978c

Please sign in to comment.