Skip to content

Commit

Permalink
[CaminoAddVal] Add nodeOwnerAuth
Browse files Browse the repository at this point in the history
  • Loading branch information
peak3d authored and c4t-ag committed Apr 26, 2023
1 parent 2a4e158 commit 32fc55f
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 38 deletions.
30 changes: 21 additions & 9 deletions e2e_tests/camino/pchain_nomock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const delegationFee: number = 10
const threshold: number = 1
const locktime: BN = new BN(0)
const memo: Buffer = Buffer.from(
"PlatformVM utility method buildAddValidatorTx to add a validator to the primary subnet"
"PlatformVM utility method buildCaminoAddValidatorTx to add a validator to the primary subnet"
)
const interestRateDenominator = new BN(1_000_000 * (365 * 24 * 60 * 60))
const dummyContractBin =
Expand Down Expand Up @@ -149,17 +149,20 @@ describe("Camino-PChain-Add-Validator", (): void => {
() =>
(async function () {
const stakeAmount: any = await pChain.getMinStake()
const unsignedTx: UnsignedTx = await pChain.buildAddValidatorTx(
const unsignedTx: UnsignedTx = await pChain.buildCaminoAddValidatorTx(
undefined,
[P(adminAddress)],
[P(adminAddress)],
[P(adminAddress)],
adminNodeId,
{
address: P(adminAddress),
auth: [[0, P(adminAddress)]]
},
startTime,
endTime,
stakeAmount.minValidatorStake,
[P(adminAddress)],
delegationFee,
locktime,
threshold,
memo
Expand All @@ -177,17 +180,20 @@ describe("Camino-PChain-Add-Validator", (): void => {
() =>
(async function () {
const stakeAmount: any = await pChain.getMinStake()
const unsignedTx: UnsignedTx = await pChain.buildAddValidatorTx(
const unsignedTx: UnsignedTx = await pChain.buildCaminoAddValidatorTx(
undefined,
[P(adminAddress)],
[P(adminAddress)],
[P(adminAddress)],
node6Id,
{
address: P(adminAddress),
auth: [[0, P(adminAddress)]]
},
startTime,
endTime,
stakeAmount.minValidatorStake,
[P(adminAddress)],
delegationFee,
locktime,
threshold,
memo
Expand Down Expand Up @@ -248,17 +254,20 @@ describe("Camino-PChain-Add-Validator", (): void => {
() =>
(async function () {
const stakeAmount: any = await pChain.getMinStake()
const unsignedTx: UnsignedTx = await pChain.buildAddValidatorTx(
const unsignedTx: UnsignedTx = await pChain.buildCaminoAddValidatorTx(
undefined,
[P(addrB)], // "X-kopernikus1s93gzmzuvv7gz8q4l83xccrdchh8mtm3xm5s2g"
[P(addrB)],
[P(addrB)],
node6Id,
{
address: P(addrB),
auth: [[0, P(addrB)]]
},
startTime,
endTime,
stakeAmount.minValidatorStake,
[P(addrB)],
delegationFee,
locktime,
threshold,
memo
Expand Down Expand Up @@ -912,17 +921,20 @@ describe("Camino-PChain-Multisig", (): void => {
])
const utxoSet: UTXOSet = platformVMUTXOResponse.utxos

const unsignedTx: UnsignedTx = await pChain.buildAddValidatorTx(
const unsignedTx: UnsignedTx = await pChain.buildCaminoAddValidatorTx(
utxoSet,
[P(multiSigAliasAddr)],
[[P(multiSigAliasAddr)], [pAddressStrings[5]]],
[P(multiSigAliasAddr)],
node7Id, // the node where the alias is registered
{
address: P(multiSigAliasAddr),
auth: [[0, pAddressStrings[5]]]
},
startTime,
endTime,
new BN(2000000000000),
[P(multiSigAliasAddr)],
0,
undefined,
threshold,
undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,20 @@ const sendAddValidatorTx = async (): Promise<any> => {
let startDate = new Date(Date.now() + 0.5 * 60 * 1000).getTime() / 1000
let endDate = startDate + 60 * 60 * 24 * 10

const unsignedTx: UnsignedTx = await pchain.buildAddValidatorTx(
const unsignedTx: UnsignedTx = await pchain.buildCaminoAddValidatorTx(
utxoSet,
[msigAlias],
[[msigAlias], pAddressStrings],
[msigAlias],
nodeID,
{
address: msigAlias,
auth: [[0, msigAliasArray[0]]]
},
new BN(startDate),
new BN(endDate),
new BN(2000000000000),
[msigAlias],
0, // delegation fee
undefined,
threshold,
undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,17 +135,20 @@ const sendAddValidatorTx = async (): Promise<any> => {
let startDate = new Date(Date.now() + 0.5 * 60 * 1000).getTime() / 1000
let endDate = startDate + 60 * 60 * 24 * 10

const unsignedTx: UnsignedTx = await pchain.buildAddValidatorTx(
const unsignedTx: UnsignedTx = await pchain.buildCaminoAddValidatorTx(
utxoSet,
[msigAlias],
[[msigAlias], pAddressStrings],
[msigAlias],
nodeID,
{
address: msigAlias,
auth: [[0, msigAliasArray[0]]]
},
new BN(startDate),
new BN(endDate),
new BN(2000000000000),
[msigAlias],
0, // delegation fee
undefined,
threshold,
undefined,
Expand Down
129 changes: 125 additions & 4 deletions src/apis/platformvm/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import { TransferableInput } from "./inputs"
import { TransferableOutput } from "./outputs"
import { Serialization, SerializedType } from "../../utils"
import { GenesisData } from "../avm"
import { Auth, LockMode, Builder, FromSigner } from "./builder"
import { Auth, LockMode, Builder, FromSigner, NodeOwner } from "./builder"
import { Network } from "../../utils/networks"
import { Spender } from "./spender"

Expand All @@ -100,6 +100,10 @@ const NanoBN = new BN(1000000000)
const rewardPercentDenom = 1000000

type FromType = String[] | String[][]
type NodeOwnerType = {
address: string
auth: [number, string][]
}

/**
* Class for interacting with a node's PlatformVMAPI
Expand Down Expand Up @@ -2007,7 +2011,7 @@ export class PlatformVMAPI extends JRPCAPI {
const minStake: BN = (await this.getMinStake())["minValidatorStake"]
if (stakeAmount.lt(minStake)) {
throw new StakeError(
"PlatformVMAPI.buildAddValidatorTx -- stake amount must be at least " +
`PlatformVMAPI.${caller} -- stake amount must be at least ` +
minStake.toString(10)
)
}
Expand All @@ -2018,7 +2022,7 @@ export class PlatformVMAPI extends JRPCAPI {
delegationFee < 0
) {
throw new DelegationFeeError(
"PlatformVMAPI.buildAddValidatorTx -- delegationFee must be a number between 0 and 100"
`PlatformVMAPI.${caller} -- delegationFee must be a number between 0 and 100`
)
}

Expand All @@ -2027,7 +2031,7 @@ export class PlatformVMAPI extends JRPCAPI {
const now: BN = UnixNow()
if (startTime.lt(now) || endTime.lte(startTime)) {
throw new TimeError(
"PlatformVMAPI.buildAddValidatorTx -- startTime must be in the future and endTime must come after startTime"
`PlatformVMAPI.${caller} -- startTime must be in the future and endTime must come after startTime`
)
}

Expand Down Expand Up @@ -2213,6 +2217,123 @@ export class PlatformVMAPI extends JRPCAPI {

return builtUnsignedTx
}

/**
* Helper function which creates an unsigned [[CaminoAddValidatorTx]]. For more granular control, you may create your own
* [[UnsignedTx]] manually and import the [[CaminoAddValidatorTx]] class directly.
*
* @param utxoset A set of UTXOs that the transaction is built on
* @param toAddresses An array of addresses as {@link https://github.com/feross/buffer|Buffer} who received the staked tokens at the end of the staking period
* @param fromAddresses An array of addresses as {@link https://github.com/feross/buffer|Buffer} who own the staking UTXOs the fees in AVAX
* @param changeAddresses An array of addresses as {@link https://github.com/feross/buffer|Buffer} who gets the change leftover from the fee payment
* @param nodeID The node ID of the validator being added.
* @param nodeOwner The address and signature indices of the registered nodeId owner.
* @param startTime The Unix time when the validator starts validating the Primary Network.
* @param endTime The Unix time when the validator stops validating the Primary Network (and staked AVAX is returned).
* @param stakeAmount The amount being delegated as a {@link https://github.com/indutny/bn.js/|BN}
* @param rewardAddresses The addresses which will recieve the rewards from the delegated stake.
* @param rewardLocktime Optional. The locktime field created in the resulting reward outputs
* @param rewardThreshold Opional. The number of signatures required to spend the funds in the resultant reward UTXO. Default 1.
* @param memo Optional contains arbitrary bytes, up to 256 bytes
* @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN}
* @param toThreshold Optional. The number of signatures required to spend the funds in the resultant UTXO
* @param changeThreshold Optional. The number of signatures required to spend the funds in the resultant change UTXO
*
* @returns An unsigned transaction created from the passed in parameters.
*/
buildCaminoAddValidatorTx = async (
utxoset: UTXOSet,
toAddresses: string[],
fromAddresses: FromType,
changeAddresses: string[],
nodeID: string,
nodeOwner: NodeOwnerType,
startTime: BN,
endTime: BN,
stakeAmount: BN,
rewardAddresses: string[],
rewardLocktime: BN = ZeroBN,
rewardThreshold: number = 1,
memo: PayloadBase | Buffer = undefined,
asOf: BN = ZeroBN,
toThreshold: number = 1,
changeThreshold: number = 1
): Promise<UnsignedTx> => {
const caller = "buildCaminoAddValidatorTx"

const to: Buffer[] = this._cleanAddressArrayBuffer(toAddresses, caller)

const fromSigner = this._parseFromSigner(fromAddresses, caller)

const change: Buffer[] = this._cleanAddressArrayBuffer(
changeAddresses,
caller
)
const rewards: Buffer[] = this._cleanAddressArrayBuffer(
rewardAddresses,
caller
)

if (memo instanceof PayloadBase) {
memo = memo.getPayload()
}

const minStake: BN = (await this.getMinStake())["minValidatorStake"]
if (stakeAmount.lt(minStake)) {
throw new StakeError(
`PlatformVMAPI.${caller} -- stake amount must be at least ` +
minStake.toString(10)
)
}

const avaxAssetID: Buffer = await this.getAVAXAssetID()

const now: BN = UnixNow()
if (startTime.lt(now) || endTime.lte(startTime)) {
throw new TimeError(
`PlatformVMAPI.${caller} -- startTime must be in the future and endTime must come after startTime`
)
}

const auth: NodeOwner = {
address: this.parseAddress(nodeOwner.address),
auth: []
}
nodeOwner.auth.forEach((o) => {
auth.auth.push([o[0], this.parseAddress(o[1])])
})

const builtUnsignedTx: UnsignedTx = await this._getBuilder(
utxoset
).buildCaminoAddValidatorTx(
this.core.getNetworkID(),
bintools.cb58Decode(this.blockchainID),
to,
fromSigner,
change,
NodeIDStringToBuffer(nodeID),
auth,
startTime,
endTime,
stakeAmount,
avaxAssetID,
rewards,
rewardLocktime,
rewardThreshold,
memo,
asOf,
toThreshold,
changeThreshold
)

if (!(await this.checkGooseEgg(builtUnsignedTx))) {
/* istanbul ignore next */
throw new GooseEggCheckError("Failed Goose Egg Check")
}

return builtUnsignedTx
}

/**
* Build an unsigned [[AddressStateTx]].
*
Expand Down
32 changes: 13 additions & 19 deletions src/apis/platformvm/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ export type FromSigner = {
signer: Buffer[]
}

export type NodeOwner = {
address: Buffer
auth: [number, Buffer][]
}

export type Auth = {
addresses: Buffer[]
threshold: number
Expand Down Expand Up @@ -741,25 +746,7 @@ export class Builder {
changeThreshold: number = 1
): Promise<UnsignedTx> => {
if (this.caminoEnabled) {
return this.buildCaminoAddValidatorTx(
networkID,
blockchainID,
toAddresses,
fromSigner,
changeAddresses,
nodeID,
startTime,
endTime,
stakeAmount,
stakeAssetID,
rewardAddresses,
rewardLocktime,
rewardThreshold,
memo,
asOf,
toThreshold,
changeThreshold
)
throw new Error("Use buildCaminoAddValidatorTx")
}

let ins: TransferableInput[] = []
Expand Down Expand Up @@ -1018,6 +1005,7 @@ export class Builder {
* @param fromSigner The addresses being used to send and verify the funds from the UTXOs {@link https://github.com/feross/buffer|Buffer}
* @param changeAddresses An array of addresses as {@link https://github.com/feross/buffer|Buffer} who gets the change leftover from the fee payment
* @param nodeID The node ID of the validator being added.
* @param nodeOwner The address and signature indices of the registered nodeId owner.
* @param startTime The Unix time when the validator starts validating the Primary Network.
* @param endTime The Unix time when the validator stops validating the Primary Network (and staked AVAX is returned).
* @param stakeAmount The amount being delegated as a {@link https://github.com/indutny/bn.js/|BN}
Expand All @@ -1038,6 +1026,7 @@ export class Builder {
fromSigner: FromSigner,
change: Buffer[],
nodeID: Buffer,
nodeOwner: NodeOwner,
startTime: BN,
endTime: BN,
stakeAmount: BN,
Expand Down Expand Up @@ -1105,6 +1094,11 @@ export class Builder {
new ParseableOutput(rewardOutputOwners)
)

nodeOwner.auth.forEach((o) => {
baseTx.addSignatureIdx(o[0], o[1])
})
owners.push(new OutputOwners([nodeOwner.address], ZeroBN, 1))

baseTx.setOutputOwners(owners)
return new UnsignedTx(baseTx)
}
Expand Down
Loading

0 comments on commit 32fc55f

Please sign in to comment.