Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 46 additions & 22 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import (
"time"

"bridgerton.audius.co/api/dbv1"
"bridgerton.audius.co/api/spl"
"bridgerton.audius.co/api/spl/programs/reward_manager"
"bridgerton.audius.co/config"
"bridgerton.audius.co/trashid"
"github.com/AudiusProject/audiusd/pkg/rewards"
adapter "github.com/axiomhq/axiom-go/adapters/zap"
"github.com/axiomhq/axiom-go/axiom"
"github.com/ethereum/go-ethereum/crypto"
"github.com/gagliardetto/solana-go/rpc"
"github.com/gofiber/contrib/fiberzap/v2"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
Expand Down Expand Up @@ -117,23 +120,42 @@ func NewApiServer(config config.Config) *ApiServer {
panic(err)
}

solanaRpc := rpc.New(config.SolanaConfig.RpcProviders[0])
rewardAttester := rewards.NewRewardAttester(privateKey, []rewards.Reward{})
transactionSender := spl.NewTransactionSender(
config.SolanaConfig.FeePayers,
config.SolanaConfig.RpcProviders,
)
rewardManagerClient, err := reward_manager.NewRewardManagerClient(
solanaRpc,
config.SolanaConfig.RewardManagerProgramID,
config.SolanaConfig.RewardManagerState,
config.SolanaConfig.RewardManagerLookupTable,
logger,
)
if err != nil {
panic(err)
}

app := &ApiServer{
App: fiber.New(fiber.Config{
JSONEncoder: json.Marshal,
JSONDecoder: json.Unmarshal,
ErrorHandler: errorHandler(logger),
}),
pool: pool,
queries: dbv1.New(pool),
logger: logger,
started: time.Now(),
resolveHandleCache: resolveHandleCache,
resolveWalletCache: resolveWalletCache,
resolveGrantCache: resolveGrantCache,
rewardAttester: *rewards.NewRewardAttester(privateKey, []rewards.Reward{}),
solanaConfig: config.SolanaConfig,
antiAbuseOracles: config.AntiAbuseOracles,
validators: config.Nodes,
pool: pool,
queries: dbv1.New(pool),
logger: logger,
started: time.Now(),
resolveHandleCache: resolveHandleCache,
resolveWalletCache: resolveWalletCache,
resolveGrantCache: resolveGrantCache,
rewardAttester: *rewardAttester,
transactionSender: *transactionSender,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if this should be solanaTransactionSender/splTransactionSender. could get confusing when we do more relay-to-core stuff

rewardManagerClient: *rewardManagerClient,
solanaConfig: config.SolanaConfig,
antiAbuseOracles: config.AntiAbuseOracles,
validators: config.Nodes,
}

app.Use(recover.New(recover.Config{
Expand Down Expand Up @@ -273,17 +295,19 @@ func NewApiServer(config config.Config) *ApiServer {

type ApiServer struct {
*fiber.App
pool *pgxpool.Pool
queries *dbv1.Queries
logger *zap.Logger
started time.Time
resolveHandleCache otter.Cache[string, int32]
resolveWalletCache otter.Cache[string, int32]
resolveGrantCache otter.Cache[string, bool]
rewardAttester rewards.RewardAttester
solanaConfig config.SolanaConfig
antiAbuseOracles []string
validators []config.Node
pool *pgxpool.Pool
queries *dbv1.Queries
logger *zap.Logger
started time.Time
resolveHandleCache otter.Cache[string, int32]
resolveWalletCache otter.Cache[string, int32]
resolveGrantCache otter.Cache[string, bool]
rewardManagerClient reward_manager.RewardManagerClient
rewardAttester rewards.RewardAttester
transactionSender spl.TransactionSender
solanaConfig config.SolanaConfig
antiAbuseOracles []string
validators []config.Node
}

func (app *ApiServer) home(c *fiber.Ctx) error {
Expand Down
1 change: 1 addition & 0 deletions api/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func TestMain(m *testing.M) {
Env: "test",
DbUrl: "postgres://postgres:example@localhost:21300/test",
DelegatePrivateKey: "0633fddb74e32b3cbc64382e405146319c11a1a52dc96598e557c5dbe2f31468",
SolanaConfig: config.SolanaConfig{RpcProviders: []string{""}},
})

// seed db
Expand Down
26 changes: 10 additions & 16 deletions api/spl/programs/reward_manager/EvaluateAttestations.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package reward_manager

import (
"encoding/hex"
"strings"

"github.com/ethereum/go-ethereum/common"
bin "github.com/gagliardetto/binary"
"github.com/gagliardetto/solana-go"
)
Expand All @@ -12,14 +10,14 @@ type EvaluateAttestation struct {
// Instruction Data
Amount uint64
DisbursementID string
ReceipientEthAddress string
ReceipientEthAddress common.Address

// Used for derivations
RewardManagerState solana.PublicKey `bin:"-" borsh_skip:"true"`
Payer solana.PublicKey `bin:"-" borsh_skip:"true"`
DestinationUserBank solana.PublicKey `bin:"-" borsh_skip:"true"`
TokenSource solana.PublicKey `bin:"-" borsh_skip:"true"`
AntiAbuseOracleEthAddress string `bin:"-" borsh_skip:"true"`
AntiAbuseOracleEthAddress common.Address `bin:"-" borsh_skip:"true"`

// Accounts
solana.AccountMetaSlice `bin:"-" borsh_skip:"true"`
Expand All @@ -35,7 +33,7 @@ func (inst *EvaluateAttestation) SetDisbursementID(challengedId string, specifie
return inst
}

func (inst *EvaluateAttestation) SetRecipientEthAddress(recipientEthAddress string) *EvaluateAttestation {
func (inst *EvaluateAttestation) SetRecipientEthAddress(recipientEthAddress common.Address) *EvaluateAttestation {
inst.ReceipientEthAddress = recipientEthAddress
return inst
}
Expand All @@ -45,7 +43,7 @@ func (inst *EvaluateAttestation) SetAmount(amount uint64) *EvaluateAttestation {
return inst
}

func (inst *EvaluateAttestation) SetAntiAbuseOracleEthAddress(antiAbuseOracleAddress string) *EvaluateAttestation {
func (inst *EvaluateAttestation) SetAntiAbuseOracleEthAddress(antiAbuseOracleAddress common.Address) *EvaluateAttestation {
inst.AntiAbuseOracleEthAddress = antiAbuseOracleAddress
return inst
}
Expand All @@ -71,8 +69,8 @@ func (inst *EvaluateAttestation) SetPayer(payer solana.PublicKey) *EvaluateAttes
}

func (inst EvaluateAttestation) Build() *Instruction {
authority, _, _ := DeriveAuthorityAccount(ProgramID, inst.RewardManagerState)
attestations, _, _ := DeriveAttestationsAccount(ProgramID, authority, inst.DisbursementID)
authority, _, _ := deriveAuthorityAccount(ProgramID, inst.RewardManagerState)
attestations, _, _ := deriveAttestationsAccount(ProgramID, authority, inst.DisbursementID)
disbursement, _, _ := deriveDisbursement(ProgramID, authority, inst.DisbursementID)
antiAbuseOracle, _, _ := deriveSender(ProgramID, authority, inst.AntiAbuseOracleEthAddress)

Expand Down Expand Up @@ -151,11 +149,7 @@ func (inst EvaluateAttestation) MarshalWithEncoder(encoder *bin.Encoder) error {
return err
}

address, err := hex.DecodeString(strings.TrimPrefix(inst.ReceipientEthAddress, "0x"))
if err != nil {
return err
}
return encoder.WriteBytes(address, false)
return encoder.WriteBytes(inst.ReceipientEthAddress.Bytes(), false)
}

func (inst *EvaluateAttestation) UnmarshalWithDecoder(decoder *bin.Decoder) error {
Expand All @@ -165,9 +159,9 @@ func (inst *EvaluateAttestation) UnmarshalWithDecoder(decoder *bin.Decoder) erro
func NewEvaluateAttestationInstruction(
challengeId string,
specifier string,
recipientEthAddress string,
recipientEthAddress common.Address,
amount uint64,
antiAbuseOracleAddress string,
antiAbuseOracleAddress common.Address,
rewardManagerState solana.PublicKey,
tokenSource solana.PublicKey,
destinationUserBank solana.PublicKey,
Expand Down
5 changes: 3 additions & 2 deletions api/spl/programs/reward_manager/EvaluateAttestations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"bridgerton.audius.co/api/spl/programs/reward_manager"
"github.com/ethereum/go-ethereum/common"
"github.com/gagliardetto/solana-go"
"github.com/stretchr/testify/require"
)
Expand All @@ -13,9 +14,9 @@ func TestEvaluateAttestationsInstruction(t *testing.T) {
// Test data
challengeId := "ft"
specifier := "37364e80"
recipientEthAddress := "0x3f6d9fcf0d4466dd5886e3b1def017adfb7916b4"
recipientEthAddress := common.HexToAddress("0x3f6d9fcf0d4466dd5886e3b1def017adfb7916b4")
amount := uint64(200000000)
antiAbuseOracleEthAddress := "0x00b6462e955dA5841b6D9e1E2529B830F00f31Bf"
antiAbuseOracleEthAddress := common.HexToAddress("0x00b6462e955dA5841b6D9e1E2529B830F00f31Bf")

// Expected Accounts
// From successful stage transaction (signature 26gT9HVMhzBDzsKcsiKREYmGcXuZhjAJpCVUu9WFNhVMyKje8SdApYc4ev3HrumZB4LEXLUaPnKyriBPLmtzwrWp)
Expand Down
11 changes: 6 additions & 5 deletions api/spl/programs/reward_manager/SubmitAttestation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package reward_manager

import (
"github.com/ethereum/go-ethereum/common"
bin "github.com/gagliardetto/binary"
"github.com/gagliardetto/solana-go"
)
Expand All @@ -10,7 +11,7 @@ type SubmitAttestation struct {
DisbursementID string

// Used for derivations
SenderEthAddress string `bin:"-" borsh_skip:"true"`
SenderEthAddress common.Address `bin:"-" borsh_skip:"true"`
RewardManagerState solana.PublicKey `bin:"-" borsh_skip:"true"`
Payer solana.PublicKey `bin:"-" borsh_skip:"true"`

Expand All @@ -28,7 +29,7 @@ func (inst *SubmitAttestation) SetDisbursementID(challengeId string, specifier s
return inst
}

func (inst *SubmitAttestation) SetSenderEthAddress(senderEthAddress string) *SubmitAttestation {
func (inst *SubmitAttestation) SetSenderEthAddress(senderEthAddress common.Address) *SubmitAttestation {
inst.SenderEthAddress = senderEthAddress
return inst
}
Expand All @@ -44,9 +45,9 @@ func (inst *SubmitAttestation) SetPayer(payer solana.PublicKey) *SubmitAttestati
}

func (inst SubmitAttestation) Build() *Instruction {
authority, _, _ := DeriveAuthorityAccount(ProgramID, inst.RewardManagerState)
authority, _, _ := deriveAuthorityAccount(ProgramID, inst.RewardManagerState)
sender, _, _ := deriveSender(ProgramID, authority, inst.SenderEthAddress)
attestations, _, _ := DeriveAttestationsAccount(ProgramID, authority, inst.DisbursementID)
attestations, _, _ := deriveAttestationsAccount(ProgramID, authority, inst.DisbursementID)

inst.AccountMetaSlice = []*solana.AccountMeta{
{
Expand Down Expand Up @@ -108,7 +109,7 @@ func (inst *SubmitAttestation) UnmarshalWithDecoder(decoder *bin.Decoder) error
func NewSubmitAttestationInstruction(
challengeId string,
specifier string,
senderEthAddress string,
senderEthAddress common.Address,
rewardManagerState solana.PublicKey,
payer solana.PublicKey,

Expand Down
13 changes: 5 additions & 8 deletions api/spl/programs/reward_manager/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"

"github.com/AudiusProject/audiusd/pkg/rewards"
"github.com/ethereum/go-ethereum/common"
bin "github.com/gagliardetto/binary"
"github.com/gagliardetto/solana-go"
)
Expand Down Expand Up @@ -125,27 +126,23 @@ func (data *AttestationsAccountData) UnmarshalWithDecoder(decoder *bin.Decoder)
return nil
}

func DeriveAuthorityAccount(programId solana.PublicKey, state solana.PublicKey) (solana.PublicKey, uint8, error) {
func deriveAuthorityAccount(programId solana.PublicKey, state solana.PublicKey) (solana.PublicKey, uint8, error) {
seeds := make([][]byte, 1)
seeds[0] = state.Bytes()[0:32]
return solana.FindProgramAddress(seeds, programId)
}

func deriveSender(programId solana.PublicKey, authority solana.PublicKey, ethAddress string) (solana.PublicKey, uint8, error) {
func deriveSender(programId solana.PublicKey, authority solana.PublicKey, ethAddress common.Address) (solana.PublicKey, uint8, error) {
senderSeedPrefix := []byte(SenderSeedPrefix)
// Remove 0x and decode hex
decodedEthAddress, err := hex.DecodeString(strings.TrimPrefix(ethAddress, "0x"))
if err != nil {
return solana.PublicKey{}, 0, err
}
decodedEthAddress := ethAddress.Bytes()
// Pad the eth address if necessary w/ leading 0
senderSeed := make([]byte, len(senderSeedPrefix)+EthAddressByteLength)
copy(senderSeed, senderSeedPrefix)
copy(senderSeed[len(senderSeed)-len(decodedEthAddress):], decodedEthAddress)
return solana.FindProgramAddress([][]byte{authority.Bytes()[0:32], senderSeed}, programId)
}

func DeriveAttestationsAccount(programId solana.PublicKey, authority solana.PublicKey, disbursementId string) (solana.PublicKey, uint8, error) {
func deriveAttestationsAccount(programId solana.PublicKey, authority solana.PublicKey, disbursementId string) (solana.PublicKey, uint8, error) {
attestationsSeed := make([]byte, len(AttestationsSeedPrefix)+len(disbursementId))
copy(attestationsSeed, []byte(AttestationsSeedPrefix))
copy(attestationsSeed[len([]byte(AttestationsSeedPrefix)):], disbursementId)
Expand Down
Loading