Skip to content

Commit

Permalink
feat(namada): fetchBondWithSlashing; epoch parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
egasimus committed Sep 13, 2024
1 parent 018c6bc commit 392fdcc
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 39 deletions.
14 changes: 9 additions & 5 deletions packages/namada/NamadaChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export default class NamadaChain extends CW.Chain {
return this.getConnection().fetchValidatorAddressesImpl()
}
fetchValidators (options?: {
epoch?: string|number|bigint,
details?: boolean,
pagination?: [number, number]
allStates?: boolean,
Expand Down Expand Up @@ -125,13 +126,16 @@ export default class NamadaChain extends CW.Chain {
fetchValidator (address: string) {
return this.getConnection().fetchValidatorImpl(address)
}
fetchValidatorStake (address: string) {
return this.getConnection().fetchValidatorStakeImpl(address)
fetchValidatorStake (address: string, epoch?: number|string|bigint) {
return this.getConnection().fetchValidatorStakeImpl(address, epoch)
}
fetchBondWithSlashing (validator: string, delegator: string, epoch?: number|string|bigint) {
return this.getConnection().fetchBondWithSlashingImpl(validator, delegator, epoch)
}
fetchDelegations (address: string) {
return this.getConnection().fetchDelegationsImpl(address)
}
fetchDelegationsAt (address: string, epoch?: number) {
fetchDelegationsAt (address: string, epoch?: number|string|bigint) {
return this.getConnection().fetchDelegationsAtImpl(address, epoch)
}
fetchGovernanceParameters () {
Expand All @@ -155,7 +159,7 @@ export default class NamadaChain extends CW.Chain {
fetchEpochDuration () {
return this.getConnection().fetchEpochDurationImpl()
}
fetchTotalStaked () {
return this.getConnection().fetchTotalStakedImpl()
fetchTotalStaked (epoch?: number|string|bigint) {
return this.getConnection().fetchTotalStakedImpl(epoch)
}
}
14 changes: 9 additions & 5 deletions packages/namada/NamadaConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export default class NamadaConnection extends CW.Connection {
return PoS.fetchValidator(this, address)
}
fetchValidatorsImpl (options?: {
epoch?: string|number|bigint,
details?: boolean,
pagination?: [number, number]
allStates?: boolean,
Expand All @@ -134,14 +135,17 @@ export default class NamadaConnection extends CW.Connection {
fetchDelegationsImpl (address: string) {
return PoS.fetchDelegations(this, address)
}
fetchDelegationsAtImpl (address: string, epoch?: number) {
fetchDelegationsAtImpl (address: string, epoch?: number|string|bigint) {
return PoS.fetchDelegationsAt(this, address, epoch)
}
fetchTotalStakedImpl () {
return PoS.fetchTotalStaked(this)
fetchTotalStakedImpl (epoch?: number|string|bigint) {
return PoS.fetchTotalStaked(this, epoch)
}
fetchValidatorStakeImpl (address: string) {
return PoS.fetchValidatorStake(this, address)
fetchValidatorStakeImpl (address: string, epoch?: number|string|bigint) {
return PoS.fetchValidatorStake(this, address, epoch)
}
fetchBondWithSlashingImpl (validator: string, delegator: string, epoch?: number|string|bigint) {
return PoS.fetchBondWithSlashing(this, validator, delegator, epoch)
}
}

Expand Down
9 changes: 5 additions & 4 deletions packages/namada/NamadaGov.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function fetchProposalInfo (
): Promise<NamadaGovernanceProposal|null> {
const proposalResponse = await connection.abciQuery(`/vp/governance/proposal/${id}`)
if (proposalResponse[0] === 0) return null
const [ votesResponse, resultResponse ] = await Promise.all([
const [ votesResponse, resultResponse ] = await Promise.all([
`/vp/governance/proposal/${id}/votes`,
`/vp/governance/stored_proposal_result/${id}`,
].map(x=>connection.abciQuery(x)))
Expand All @@ -32,7 +32,6 @@ export async function fetchProposalInfo (
const result = (resultResponse[0] === 0) ? null
: decodeResultResponse(connection.decode.gov_result(resultResponse.slice(1)) as
Required<ReturnType<NamadaDecoder["gov_result"]>>)

return { id: BigInt(id), proposal, votes, result }
}

Expand Down Expand Up @@ -65,7 +64,7 @@ const decodeResultResponse = (
): NamadaGovernanceProposalResult => ({
...decoded,
turnout: String(turnout),
turnoutPercent: (decoded.totalVotingPower! > 0) ? percent(turnout, decoded.totalVotingPower!) : '0',
turnoutPercent: (decoded.totalVotingPower! > 0) ? percent2(turnout, decoded.totalVotingPower!) : '0',
yayPercent: (turnout > 0) ? percent(decoded.totalYayPower!, turnout) : '0',
nayPercent: (turnout > 0) ? percent(decoded.totalNayPower!, turnout) : '0',
abstainPercent: (turnout > 0) ? percent(decoded.totalAbstainPower!, turnout) : '0',
Expand Down Expand Up @@ -102,7 +101,9 @@ interface NamadaGovernanceProposalResult {
}

const percent = (a: string|number|bigint, b: string|number|bigint) =>
((Number(BigInt(a) * 1000000n / BigInt(b)) / 10000).toFixed(2) + '%').padStart(7)
((Number(BigInt(a) * 1000000n / BigInt(b)) / 10000).toFixed(2) + '%')
const percent2 = (a: string|number|bigint, b: string|number|bigint) =>
((Number(BigInt(a) * 1000000n / BigInt(b)) / 1000000).toFixed(2) + '%')

export {
NamadaGovernanceProposal as Proposal,
Expand Down
80 changes: 55 additions & 25 deletions packages/namada/NamadaPoS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export async function fetchStakingParameters (connection: NamadaConnection) {
return connection.decode.pos_parameters(binary)
}

export async function fetchTotalStaked (connection: NamadaConnection) {
const binary = await connection.abciQuery("/vp/pos/total_stake")
export async function fetchTotalStaked (connection: NamadaConnection, epoch?: number|bigint|string) {
let query = "/vp/pos/total_stake"
if (epoch) query += `/${epoch}`
const binary = await connection.abciQuery(query)
return decode(u64, binary)
}

Expand Down Expand Up @@ -62,6 +64,7 @@ export { NamadaValidator as Validator }
export async function fetchValidators (
connection: NamadaConnection,
options: Partial<Parameters<typeof Staking.getValidators>[1]> & {
epoch?: number|string|bigint
tendermintMetadata?: 'parallel'|'sequential'|boolean
namadaMetadata?: 'parallel'|'sequential'|boolean
} = {}
Expand All @@ -72,7 +75,7 @@ export async function fetchValidators (
// This is the full list of validators known to the chain.
// However, it contains no other data than the identifier.
// The rest we will have to piece together ourselves.
const namadaAddresses = await fetchValidatorAddresses(connection)
const namadaAddresses = await fetchValidatorAddresses(connection, options?.epoch)
for (const namadaAddress of namadaAddresses) {
validatorsByNamadaAddress[namadaAddress] = new NamadaValidator({
chain: connection.chain,
Expand Down Expand Up @@ -185,13 +188,14 @@ export async function fetchValidators (
}

/** Generator implementation of fetchValidators. */
export async function * fetchValidatorsIter (
connection: NamadaConnection,
options?: { parallel?: boolean, addresses?: string[] }
) {
const namadaAddresses = options?.addresses?.length
? options.addresses
: await fetchValidatorAddresses(connection)
export async function * fetchValidatorsIter (connection: NamadaConnection, options?: {
epoch?: number|string|bigint,
parallel?: boolean,
addresses?: string[]
}) {
const { addresses = [], epoch, parallel = false } = options || {}
const namadaAddresses = addresses?.length
? addresses : await fetchValidatorAddresses(connection, epoch)
const tendermintMetadata = (await Staking.getValidators(connection)).reduce((vs, v)=>
Object.assign(vs, {[v.publicKey]: v}), {}) as Record<string, {
address: string
Expand Down Expand Up @@ -224,7 +228,9 @@ export async function * fetchValidatorsIter (
.then(binary => validator.state = connection.decode.pos_validator_state(binary))
.catch(warn(`Failed to provide validator state for ${addr}`)),

() => connection.abciQuery(`/vp/pos/validator/stake/${addr}`)
() => connection.abciQuery(
`/vp/pos/validator/stake/${addr}` + (epoch ? `/${epoch}` : ``)
)
.then(binary => binary[0] && (validator.stake = decode(u256, binary.slice(1))))
.catch(warn(`Failed to provide validator stake for ${addr}`)),

Expand All @@ -237,22 +243,26 @@ export async function * fetchValidatorsIter (
warn(`Failed to decode validator public key for ${addr}`)
)
]
await optionallyParallel(options?.parallel, requests)
await optionallyParallel(parallel, requests)
yield validator
}
}

export async function fetchValidatorAddresses (connection: NamadaConnection): Promise<Address[]> {
const binary = await connection.abciQuery("/vp/pos/validator/addresses")
export async function fetchValidatorAddresses (
connection: NamadaConnection, epoch?: number|string|bigint
): Promise<Address[]> {
let query = "/vp/pos/validator/addresses"
if (epoch) query = query + `/${epoch}`
const binary = await connection.abciQuery(query)
return connection.decode.addresses(binary)
}

export async function fetchValidatorDetails (
connection: NamadaConnection,
options?: { parallel?: boolean, validator?: Partial<NamadaValidator> }
) {
const validator = options?.validator || {}

export async function fetchValidatorDetails (connection: NamadaConnection, options?: {
epoch?: number|string|bigint,
parallel?: boolean,
validator?: Partial<NamadaValidator>
}) {
const { epoch, validator = {}, parallel = false } = options || {}
if (!validator.namadaAddress) {
if (!validator.address) {
throw new Error('missing tendermint or namada address for validator')
Expand All @@ -274,10 +284,10 @@ export async function fetchValidatorDetails (
() => connection.abciQuery(`/vp/pos/validator/commission/${v}`)
.then(binary => validator.commission = connection.decode.pos_commission_pair(binary))
.catch(warn(`Failed to provide validator commission pair for ${v}`)),
() => connection.abciQuery(`/vp/pos/validator/state/${v}`)
() => connection.abciQuery(`/vp/pos/validator/state/${v}` + (epoch?`/${epoch}`:''))
.then(binary => validator.state = connection.decode.pos_validator_state(binary))
.catch(warn(`Failed to provide validator state for ${v}`)),
() => connection.abciQuery(`/vp/pos/validator/stake/${v}`)
() => connection.abciQuery(`/vp/pos/validator/stake/${v}` + (epoch?`/${epoch}`:''))
.then(binary => binary[0] && (validator.stake = decode(u256, binary.slice(1))))
.catch(warn(`Failed to provide validator stake for ${v}`)),
() => connection.abciQuery(`/vp/pos/validator/consensus_key/${v}`)
Expand Down Expand Up @@ -328,8 +338,14 @@ export async function fetchValidator (connection: NamadaConnection, namadaAddres
}).fetchDetails()
}

export async function fetchValidatorStake (connection: NamadaConnection, address: Address) {
const totalStake = await connection.abciQuery(`/vp/pos/validator/stake/${address}`)
export async function fetchValidatorStake (
connection: NamadaConnection,
address: Address,
epoch?: number|bigint|string
) {
let query = `/vp/pos/validator/stake/${address}`
if (epoch) query += `/${epoch}`
const totalStake = await connection.abciQuery(query)
return decode(u256, totalStake)
}

Expand All @@ -339,7 +355,9 @@ export async function fetchDelegations (connection: NamadaConnection, address: A
}

export async function fetchDelegationsAt (
connection: NamadaConnection, address: Address, epoch?: number
connection: NamadaConnection,
address: Address,
epoch?: number|string|bigint
): Promise<Record<string, bigint>> {
let query = `/vp/pos/delegations_at/${address}`
epoch = Number(epoch)
Expand All @@ -349,3 +367,15 @@ export async function fetchDelegationsAt (
const binary = await connection.abciQuery(query)
return connection.decode.address_to_amount(binary) as Record<string, bigint>
}

export async function fetchBondWithSlashing (
connection: NamadaConnection,
validator: Address,
delegator: Address,
epoch?: number|bigint|string
) {
let query = `/vp/pos/bond_with_slashing/${validator}/${delegator}`
if (epoch) query += `/${epoch}`
const totalStake = await connection.abciQuery(query)
return decode(u256, totalStake)
}

0 comments on commit 392fdcc

Please sign in to comment.