Skip to content

Commit

Permalink
review comments and remove stakingOutputIndex from input
Browse files Browse the repository at this point in the history
  • Loading branch information
jrwbabylonlab committed Oct 25, 2024
1 parent a4ce6d7 commit 4e8cd70
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 195 deletions.
52 changes: 26 additions & 26 deletions src/staking/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import {
withdrawEarlyUnbondedTransaction,
withdrawTimelockUnbondedTransaction
} from "./transactions";
import {
deriveAddressFromPkScript,
import {
isTaproot,
isValidBitcoinAddress, isValidNoCoordPublicKey
} from "../utils/btc";
import { validateParams, validateStakingTimelock, validateStakingTxInputData, validateStakingTxOutputIndex } from "../utils/staking";
import { deriveStakingOutputAddress, findMatchingStakingTxOutputIndex, validateParams, validateStakingTimelock, validateStakingTxInputData } from "../utils/staking";
import { PsbtTransactionResult } from "../types/transaction";
import { toBuffers } from "../utils/staking";
export * from "./stakingScript";
Expand Down Expand Up @@ -162,11 +161,16 @@ export class Staking {
*/
public createUnbondingTransaction(
stakingTx: Transaction,
stakingOutputIndex: number,
) : PsbtTransactionResult {
validateStakingTxOutputIndex(stakingTx, stakingOutputIndex);
) : PsbtTransactionResult {
// Build scripts
const scripts = this.buildScripts();

// Reconstruct the stakingOutputIndex
const stakingOutputIndex = findMatchingStakingTxOutputIndex(
stakingTx,
deriveStakingOutputAddress(scripts, this.network),
this.network,
)
// Create the unbonding transaction
try {
const { psbt } = unbondingTransaction(
Expand Down Expand Up @@ -220,23 +224,28 @@ export class Staking {
}

/**
* Create a withdrawal transaction that spends a naturally expired staking transaction for observable staking.
* Create a withdrawal transaction that spends a naturally expired staking
* transaction.
*
* @param {Transaction} stakingTx - The staking transaction to withdraw from.
* @param {number} feeRate - The fee rate for the transaction in satoshis per byte.
*
* @returns {PsbtTransactionResult} - An object containing the unsigned psbt and fee
*
* @throws {StakingError} - If the delegation is invalid or the transaction cannot be built
*/
public createWithdrawTimelockUnbondedTransaction(
stakingTx: Transaction,
stakingOutputIndex: number,
feeRate: number,
): PsbtTransactionResult {
validateStakingTxOutputIndex(stakingTx, stakingOutputIndex);
// Build scripts
const scripts = this.buildScripts();

// Reconstruct the stakingOutputIndex
const stakingOutputIndex = findMatchingStakingTxOutputIndex(
stakingTx,
deriveStakingOutputAddress(scripts, this.network),
this.network,
)

// Create the timelock unbonded transaction
try {
return withdrawTimelockUnbondedTransaction(
Expand All @@ -256,16 +265,15 @@ export class Staking {
}

/**
* Create a slash timelock unbonded transaction for staking.
* Create a staking slashing transaction.
*
* @param {Transaction} stakingTx - The staking transaction to slash.
* without coordinates.
*
* @returns {PsbtTransactionResult} - An object containing the unsigned psbt and fee
*
* @throws {StakingError} - If the delegation is invalid or the transaction cannot be built
*/
public createSlashTimelockUnbondedTransaction(
public createStakingOutputSlashingTransaction(
stakingTx: Transaction,
) : PsbtTransactionResult {
if (!this.params.slashing) {
Expand All @@ -274,9 +282,6 @@ export class Staking {
"Slashing parameters are missing",
);
}
const slashingAddress = deriveAddressFromPkScript(
this.params.slashing.slashingPkScript, this.network,
);

// Build scripts
const scripts = this.buildScripts();
Expand All @@ -286,7 +291,7 @@ export class Staking {
const { psbt } = slashTimelockUnbondedTransaction(
scripts,
stakingTx,
slashingAddress,
this.params.slashing.slashingPkScriptHex,
this.params.slashing.slashingRate,
this.params.slashing.minSlashingTxFeeSat,
this.network,
Expand All @@ -301,15 +306,14 @@ export class Staking {
}

/**
* Create a slash early unbonded transaction for staking.
* Create a unbonding slashing transaction.
*
* @param {Transaction} unbondingTx - The unbonding transaction to slash.
*
* @returns {PsbtTransactionResult} - An object containing the unsigned psbt and fee
*
* @throws {StakingError} - If the delegation is invalid or the transaction cannot be built
*/
public createSlashEarlyUnbondedTransaction(
public createUnbondingOutputSlashingTransaction(
unbondingTx: Transaction,
): PsbtTransactionResult {
if (!this.params.slashing) {
Expand All @@ -318,10 +322,6 @@ export class Staking {
"Slashing parameters are missing",
);
}
const slashingAddress = deriveAddressFromPkScript(
this.params.slashing.slashingPkScript, this.network,
);

// Build scripts
const scripts = this.buildScripts();

Expand All @@ -330,7 +330,7 @@ export class Staking {
const { psbt } = slashEarlyUnbondedTransaction(
scripts,
unbondingTx,
slashingAddress,
this.params.slashing.slashingPkScriptHex,
this.params.slashing.slashingRate,
this.params.slashing.minSlashingTxFeeSat,
this.network,
Expand Down
46 changes: 11 additions & 35 deletions src/staking/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ function withdrawalTransaction(
*
* @param {Object} scripts - The scripts used in the transaction.
* @param {Transaction} stakingTransaction - The original staking transaction.
* @param {string} slashingAddress - The address to send the slashed funds to.
* @param {string} slashingPkScriptHex - The public key script to send the slashed funds to.
* @param {number} slashingRate - The rate at which the funds are slashed.
* @param {number} minimumFee - The minimum fee for the transaction in satoshis.
* @param {networks.Network} network - The Bitcoin network.
Expand All @@ -394,7 +394,7 @@ export function slashTimelockUnbondedTransaction(
unbondingTimelockScript: Buffer;
},
stakingTransaction: Transaction,
slashingAddress: string,
slashingPkScriptHex: string,
slashingRate: number,
minimumFee: number,
network: networks.Network,
Expand All @@ -413,7 +413,7 @@ export function slashTimelockUnbondedTransaction(
},
slashingScriptTree,
stakingTransaction,
slashingAddress,
slashingPkScriptHex,
slashingRate,
minimumFee,
network,
Expand All @@ -427,26 +427,13 @@ export function slashTimelockUnbondedTransaction(
* This transaction spends the staking output of the staking transaction and distributes the funds
* according to the specified slashing rate.
*
* Outputs:
* Transaction outputs:
* - The first output sends `input * slashing_rate` funds to the slashing address.
* - The second output sends `input * (1 - slashing_rate) - fee` funds back to the user's address.
*
* Inputs:
* - scripts: Scripts used to construct the taproot output.
* - slashingScript: Script for the slashing condition.
* - unbondingTimelockScript: Script for the unbonding timelock condition.
* - transaction: The unbonding transaction.
* - slashingAddress: The address to send the slashed funds to.
* - slashingRate: The rate at which the funds are slashed (0 < slashingRate < 1).
* - minimumFee: The minimum fee for the transaction in satoshis.
* - network: The Bitcoin network.
*
* Returns:
* - psbt: The partially signed transaction (PSBT).
*
* @param {Object} scripts - The scripts used in the transaction. e.g slashingScript, unbondingTimelockScript
* @param {Transaction} unbondingTx - The unbonding transaction.
* @param {string} slashingAddress - The address to send the slashed funds to.
* @param {string} slashingPkScriptHex - The public key script to send the slashed funds to.
* @param {number} slashingRate - The rate at which the funds are slashed.
* @param {number} minimumSlashingFee - The minimum fee for the transaction in satoshis.
* @param {networks.Network} network - The Bitcoin network.
Expand All @@ -458,7 +445,7 @@ export function slashEarlyUnbondedTransaction(
unbondingTimelockScript: Buffer;
},
unbondingTx: Transaction,
slashingAddress: string,
slashingPkScriptHex: string,
slashingRate: number,
minimumSlashingFee: number,
network: networks.Network,
Expand All @@ -478,7 +465,7 @@ export function slashEarlyUnbondedTransaction(
},
unbondingScriptTree,
unbondingTx,
slashingAddress,
slashingPkScriptHex,
slashingRate,
minimumSlashingFee,
network,
Expand All @@ -492,24 +479,13 @@ export function slashEarlyUnbondedTransaction(
* This transaction spends the staking output of the staking transaction and distributes the funds
* according to the specified slashing rate.
*
* Outputs:
* Transaction outputs:
* - The first output sends `input * slashing_rate` funds to the slashing address.
* - The second output sends `input * (1 - slashing_rate) - fee` funds back to the user's address.
*
* Inputs:
* - scripts: Scripts used to construct the taproot output.
* - slashingScript: Script for the slashing condition.
* - unbondingTimelockScript: Script for the unbonding timelock condition.
* - transaction: The original staking/unbonding transaction.
* - slashingAddress: The address to send the slashed funds to.
* - slashingRate: The rate at which the funds are slashed (0 < slashingRate < 1).
* - minimumFee: The minimum fee for the transaction in satoshis.
* - network: The Bitcoin network.
* - outputIndex: The index of the output to be spent in the original transaction (default is 0).
*
* @param {Object} scripts - The scripts used in the transaction. e.g slashingScript, unbondingTimelockScript
* @param {Transaction} transaction - The original staking/unbonding transaction.
* @param {string} slashingAddress - The address to send the slashed funds to.
* @param {string} slashingPkScriptHex - The public key script to send the slashed funds to.
* @param {number} slashingRate - The rate at which the funds are slashed. Two decimal places, otherwise it will be rounded down.
* @param {number} minimumFee - The minimum fee for the transaction in satoshis.
* @param {networks.Network} network - The Bitcoin network.
Expand All @@ -523,7 +499,7 @@ function slashingTransaction(
},
scriptTree: Taptree,
transaction: Transaction,
slashingAddress: string,
slashingPkScriptHex: string,
slashingRate: number,
minimumFee: number,
network: networks.Network,
Expand Down Expand Up @@ -601,7 +577,7 @@ function slashingTransaction(

// Add the slashing output
psbt.addOutput({
address: slashingAddress,
script: Buffer.from(slashingPkScriptHex, "hex"),
value: slashingAmount,
});

Expand Down
2 changes: 1 addition & 1 deletion src/types/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface StakingParams {
maxStakingTimeBlocks: number;
minStakingTimeBlocks: number;
slashing?: {
slashingPkScript: string;
slashingPkScriptHex: string;
slashingRate: number;
minSlashingTxFeeSat: number;
}
Expand Down
18 changes: 0 additions & 18 deletions src/utils/btc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,3 @@ const validateNoCoordPublicKeyBuffer = (pkBuffer: Buffer): boolean => {
ecc.isPoint(compressedKeyEven) || ecc.isPoint(compressedKeyOdd)
);
};

/**
* Derive the Bitcoin address from the public key script.
*
* @param {string} scriptPubKey - The public key script in hex.
* @param {networks.Network} network - The Bitcoin network (e.g., bitcoin.networks.bitcoin).
*
* @returns {string} - The Bitcoin address.
* @throws {Error} - If the address cannot be derived from the public key script.
*/
export const deriveAddressFromPkScript = (scriptPubKey: string, network: networks.Network): string => {
try {
const scriptPubKeyBuffer = Buffer.from(scriptPubKey, "hex");
return address.fromOutputScript(scriptPubKeyBuffer, network);
} catch (error) {
throw new Error(`Failed to derive address from public key script: ${error}`);
}
};
Loading

0 comments on commit 4e8cd70

Please sign in to comment.