Skip to content

Commit

Permalink
⚡️ Load balanced RPC + index + better reward schema
Browse files Browse the repository at this point in the history
  • Loading branch information
KONFeature committed Jul 5, 2024
1 parent 2183a71 commit 7958c50
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 84 deletions.
32 changes: 20 additions & 12 deletions ponder.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createConfig, mergeAbis } from "@ponder/core";
import { http, fallback, parseAbiItem } from "viem";
import { createConfig, loadBalance, mergeAbis, rateLimit } from "@ponder/core";
import { http, parseAbiItem } from "viem";
import {
interactionCampaignAbi,
referralCampaignAbi,
Expand Down Expand Up @@ -28,18 +28,21 @@ export default createConfig({
// Testnets
arbitrumSepolia: {
chainId: 421614,
transport: fallback([
http(
`https://arbitrum-sepolia.blockpi.network/v1/rpc/${process.env.BLOCKPI_API_KEY_ARB_SEPOLIA}`
transport: loadBalance([
rateLimit(
http(
`https://arbitrum-sepolia.blockpi.network/v1/rpc/${process.env.BLOCKPI_API_KEY_ARB_SEPOLIA}`
),
{ requestsPerSecond: 20, browser: false }
),
http(
`https://arb-sepolia.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`
rateLimit(
http(
`https://arb-sepolia.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`
),
{ requestsPerSecond: 20, browser: false }
),
http(),
], {
// Huge retry delay to avoid spamming
retryDelay: 600
}),
rateLimit(http(), { requestsPerSecond: 5, browser: false }),
]),
...pollingConfig,
},
},
Expand All @@ -51,6 +54,7 @@ export default createConfig({
network: {
arbitrumSepolia: {
startBlock: 35765963,
maxBlockRange: 5000,
},
/*arbitrum: {
startBlock: 203956680,
Expand All @@ -73,6 +77,7 @@ export default createConfig({
network: {
arbitrumSepolia: {
startBlock: 54321880,
maxBlockRange: 5000,
},
},
},
Expand All @@ -83,6 +88,7 @@ export default createConfig({
network: {
arbitrumSepolia: {
startBlock: 60118981,
maxBlockRange: 5000,
},
},
},
Expand All @@ -103,6 +109,7 @@ export default createConfig({
network: {
arbitrumSepolia: {
startBlock: 60118981,
maxBlockRange: 5000,
},
},
},
Expand All @@ -117,6 +124,7 @@ export default createConfig({
network: {
arbitrumSepolia: {
startBlock: 60118981,
maxBlockRange: 5000,
},
},
},
Expand Down
171 changes: 106 additions & 65 deletions ponder.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,78 +117,119 @@ export default createSchema((p) => ({

capResets: p.many("CampaignCapReset.campaignId"),
}),
CampaignCapReset: p.createTable({
id: p.string(), // campaign address + timestamp

campaignId: p.hex().references("Campaign.id"),
campaign: p.one("campaignId"),

timestamp: p.bigint(),
previousTimestamp: p.bigint(),
distributedAmount: p.bigint(),
}),
CampaignCapReset: p.createTable(
{
id: p.string(), // campaign address + timestamp

campaignId: p.hex().references("Campaign.id"),
campaign: p.one("campaignId"),

timestamp: p.bigint(),
previousTimestamp: p.bigint(),
distributedAmount: p.bigint(),
},
{
campaignIndex: p.index("campaignId"),
}
),

// Press events
PressEvent: p.createTable({
id: p.string(),
PressEvent: p.createTable(
{
id: p.string(),

interactionId: p.hex().references("ContentInteractionContract.id"),
interaction: p.one("interactionId"),
interactionId: p.hex().references("ContentInteractionContract.id"),
interaction: p.one("interactionId"),

user: p.hex(),
type: p.enum("PressEventType"),
data: p.json(),
user: p.hex(),
type: p.enum("PressEventType"),
data: p.json(),

timestamp: p.bigint(),
}),
timestamp: p.bigint(),
},
{
interactionIndex: p.index("interactionId"),
userIndex: p.index("user"),

userInteractionIndex: p.index(["user", "interactionId"]),
}
),

PressEventType: p.createEnum(["OPEN_ARTICLE", "READ_ARTICLE", "REFERRED"]),

// Rewards related stuff
RewardingContract: p.createTable({
// Address of the rewarding contract
id: p.hex(),

// Address of the token that will be distributed
token: p.hex(),

// All the rewards
rewards: p.many("Reward.contractId"),
}),
Reward: p.createTable({
id: p.string(), // reward contract + user

contractId: p.hex().references("RewardingContract.id"),
contract: p.one("contractId"),

user: p.hex(),

pendingAmount: p.bigint(),
totalAmount: p.bigint(),

rewardAddedEvents: p.many("RewardAddedEvent.rewardId"),
rewardClaimedEvents: p.many("RewardClaimedEvent.rewardId"),
}),
RewardAddedEvent: p.createTable({
id: p.string(),

rewardId: p.string().references("Reward.id"),
reward: p.one("rewardId"),

amount: p.bigint(),

txHash: p.hex(),
timestamp: p.bigint(),
}),
RewardClaimedEvent: p.createTable({
id: p.string(),

rewardId: p.string().references("Reward.id"),
reward: p.one("rewardId"),

amount: p.bigint(),

txHash: p.hex(),
timestamp: p.bigint(),
}),
RewardingContract: p.createTable(
{
// Address of the rewarding contract
id: p.hex(),

// Address of the token that will be distributed
token: p.hex(),

// The total amount distributed and claimed
totalDistributed: p.bigint(),
totalClaimed: p.bigint(),

// All the rewards
rewards: p.many("Reward.contractId"),
},
{
tokenIndex: p.index("token"),
}
),
Reward: p.createTable(
{
id: p.string(), // reward contract + user

contractId: p.hex().references("RewardingContract.id"),
contract: p.one("contractId"),

user: p.hex(),

pendingAmount: p.bigint(),
totalReceived: p.bigint(),
totalClaimed: p.bigint(),

rewardAddedEvents: p.many("RewardAddedEvent.rewardId"),
rewardClaimedEvents: p.many("RewardClaimedEvent.rewardId"),
},
{
userIndex: p.index("user"),
contractIndex: p.index("contractId"),

userContractIndex: p.index(["user", "contractId"]),
}
),
RewardAddedEvent: p.createTable(
{
id: p.string(),

rewardId: p.string().references("Reward.id"),
reward: p.one("rewardId"),

amount: p.bigint(),

txHash: p.hex(),
timestamp: p.bigint(),
},
{
rewardIndex: p.index("rewardId"),
}
),
RewardClaimedEvent: p.createTable(
{
id: p.string(),

rewardId: p.string().references("Reward.id"),
reward: p.one("rewardId"),

amount: p.bigint(),

txHash: p.hex(),
timestamp: p.bigint(),
},
{
rewardIndex: p.index("rewardId"),
}
),
}));
34 changes: 28 additions & 6 deletions src/campaignReward.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@ import type { Address } from "viem";
import { referralCampaignAbi } from "../abis/frak-campaign-abis";

ponder.on("Campaigns:RewardAdded", async ({ event, context }) => {
const { Reward, RewardAddedEvent } = context.db;
const { RewardingContract, Reward, RewardAddedEvent } = context.db;

// Try to find a rewarding contract for the given event emitter
const rewardingContract = await getRewardingContract({
contract: event.log.address,
context,
});

// Update rewarding contract
await RewardingContract.update({
id: rewardingContract.id,
data: {
totalDistributed:
rewardingContract.totalDistributed + event.args.amount,
},
});

// Update the current user reward (insert it if not found)
const rewardId = `${event.log.address}-${event.args.user}`;
await Reward.upsert({
Expand All @@ -19,11 +28,12 @@ ponder.on("Campaigns:RewardAdded", async ({ event, context }) => {
contractId: rewardingContract.id,
user: event.args.user,
pendingAmount: event.args.amount,
totalAmount: event.args.amount,
totalReceived: event.args.amount,
totalClaimed: 0n,
},
update: ({ current }) => ({
pendingAmount: current.pendingAmount + event.args.amount,
totalAmount: current.totalAmount + event.args.amount,
totalReceived: current.totalReceived + event.args.amount,
}),
});

Expand All @@ -40,26 +50,36 @@ ponder.on("Campaigns:RewardAdded", async ({ event, context }) => {
});

ponder.on("Campaigns:RewardClaimed", async ({ event, context }) => {
const { Reward, RewardClaimedEvent } = context.db;
const { RewardingContract, Reward, RewardClaimedEvent } = context.db;

// Try to find a rewarding contract for the given event emitter
const rewardingContract = await getRewardingContract({
contract: event.log.address,
context,
});

// Update rewarding contract
await RewardingContract.update({
id: rewardingContract.id,
data: {
totalClaimed: rewardingContract.totalClaimed + event.args.amount,
},
});

// Update the current user reward (insert it if not found)
const rewardId = `${event.log.address}-${event.args.user}`;
await Reward.upsert({
id: rewardId,
create: {
contractId: rewardingContract.id,
user: event.args.user,
pendingAmount: -event.args.amount,
totalAmount: 0n,
totalClaimed: event.args.amount,
totalReceived: 0n,
pendingAmount: 0n,
},
update: ({ current }) => ({
pendingAmount: current.pendingAmount - event.args.amount,
totalClaimed: current.totalClaimed + event.args.amount,
}),
});

Expand Down Expand Up @@ -104,6 +124,8 @@ async function getRewardingContract({
id: contract,
data: {
token,
totalDistributed: 0n,
totalClaimed: 0n,
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion sst.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function IndexerStack({ app, stack }: StackContext) {
// BlockPi rpcs
new Config.Secret(stack, "BLOCKPI_API_KEY_ARB_SEPOLIA"),
// Alchemy RPC
new Config.Secret(stack, "ALCHEMY_API_KEY")
new Config.Secret(stack, "ALCHEMY_API_KEY"),
];

// Get our CDK secrets map
Expand Down

0 comments on commit 7958c50

Please sign in to comment.