Skip to content

Commit

Permalink
Fix signature in SDK rewards (#8195)
Browse files Browse the repository at this point in the history
  • Loading branch information
rickyrombo authored Apr 23, 2024
1 parent 2789c96 commit b65db45
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/new-taxis-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@audius/spl': patch
---

Fixes RewardManagerProgram getSubmittedAttestations to account for the program padding the verified messages to 128 bytes
5 changes: 5 additions & 0 deletions .changeset/plenty-toes-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@audius/spl': patch
---

Fixes RewardManagerProgram signature parsing when service attestation signature is less than 64 bytes
15 changes: 10 additions & 5 deletions packages/spl/src/reward-manager/RewardManagerProgram.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { seq, struct, u8 } from '@solana/buffer-layout'
import { blob, seq, struct, u8 } from '@solana/buffer-layout'
import { publicKey, u64 } from '@solana/buffer-layout-utils'
import { TOKEN_PROGRAM_ID } from '@solana/spl-token'
import {
Expand Down Expand Up @@ -80,11 +80,16 @@ export class RewardManagerProgram {
attestationsAccountData: struct<AttestationsAccountData>([
u8('version'),
publicKey('rewardManagerState'),
u8('count'),
seq(
struct<VerifiedMessage>([
u8('index'),
ethAddress('senderEthAddress'),
attestationLayout('attestation'),
attestationLayout('message'),
// Though the actual attestation message is only 83 bytes, we allocate
// 128 bytes for each element of this array on the program side.
// Thus we add 45 bytes of padding here to be consistent.
// See: https://github.com/AudiusProject/audius-protocol/blob/dde78ad7e26d9f6fb358fef5d240c5c7e2d25c66/solana-programs/reward-manager/program/src/state/verified_messages.rs#L99
blob(45),
ethAddress('operator')
]),
3,
Expand Down Expand Up @@ -593,9 +598,9 @@ export class RewardManagerProgram {
const strippedSignature = signature
.substring(0, signature.length - 2)
.replace('0x', '')
.padStart(128, '0')
.substring(0, 128)
const signatureBuffer = Buffer.from(strippedSignature, 'hex')
const fixedBuf = Buffer.alloc(64, 0)
signatureBuffer.copy(fixedBuf, 64 - signatureBuffer.length)
return {
signature: signatureBuffer,
recoveryId: recoveryIdBuffer.readInt8()
Expand Down
5 changes: 4 additions & 1 deletion packages/spl/src/reward-manager/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,17 @@ export type Attestation = {
}

export type VerifiedMessage = {
index: number
senderEthAddress: string
attestation: Attestation
// Hint to make types not complain when adding empty padding for
// the array of verified messages in the account data.
_: Uint8Array
operator: string
}

export type AttestationsAccountData = {
version: number
rewardManagerState: PublicKey
count: number
messages: VerifiedMessage[]
}
4 changes: 2 additions & 2 deletions packages/web/src/common/store/pages/audio-rewards/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ function* claimChallengeRewardAsync(
})
// Handle the individual specifier failures here to let the other
// ones continue to claim and not reject the all() call.
.catch((error) => {
.catch((error: unknown) => {
return {
...specifierWithAmount,
error
Expand All @@ -296,7 +296,7 @@ function* claimChallengeRewardAsync(
const error =
res.error instanceof Error ? res.error : new Error(String(res.error))
console.error(
`Failed to claim specifier: ${res.specifier} for amount: ${res.amount} with error:`,
`Failed to claim challenge: ${challengeId} specifier: ${res.specifier} for amount: ${res.amount} with error:`,
error
)
yield* call(reportToSentry, {
Expand Down
16 changes: 15 additions & 1 deletion packages/web/src/store/errors/reportToSentry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ErrorLevel, ReportToSentryArgs } from '@audius/common/models'
import { getErrorMessage } from '@audius/common/utils'
import { ResponseError } from '@audius/sdk'
import { withScope, captureException } from '@sentry/browser'
import type { SeverityLevel } from '@sentry/types'

Expand All @@ -26,6 +27,9 @@ const jsLoggerMapping: { [level in ErrorLevel]: ConsoleLoggingMethod } = {
Log: 'log'
}

const isResponseError = (error: Error): error is ResponseError =>
'response' in error && error.response instanceof Response

/**
* Helper fn that reports to sentry while creating a localized scope to contain additional data
* Also logs to console with the appropriate level (console.log, console.warn, console.error, etc)
Expand All @@ -38,11 +42,21 @@ export const reportToSentry = async ({
tags
}: ReportToSentryArgs) => {
try {
withScope((scope) => {
withScope(async (scope) => {
if (level) {
const sentryLevel = Levels[level]
scope.setLevel(sentryLevel)
}
if (isResponseError(error)) {
const responseBody =
(await error.response.json().catch()) ??
(await error.response.text().catch())
additionalInfo = {
...additionalInfo,
response: error.response,
responseBody
}
}
if (additionalInfo) {
scope.setContext('additionalInfo', additionalInfo)
}
Expand Down

0 comments on commit b65db45

Please sign in to comment.