Skip to main content
added 653 characters in body
Source Link
Ademola
  • 3.9k
  • 3
  • 20

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle or hash-chain solution, but this might be expensive wrt compute). Do you mind sharing your use-case in this scenario?

EDIT: Based on additional context provided, it seems like what you'd need is a pda for each user that tracks how much SOL they purchased, and a shared pda for all users that tracks how much SOL has been purchased in total. Then you wouldn't need to always store and update the equivalent token amount, as how much tokens a user is entitled do be dynamically calculated during the claim/distribution step using the information outlined above.

If there's multiple rounds of claim/distribution, you should also consider adjusting your program to take previously claimed tokens into account in your calculations to prevent a double-allocation.

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle or hash-chain solution, but this might be expensive wrt compute). Do you mind sharing your use-case in this scenario?

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle or hash-chain solution, but this might be expensive wrt compute). Do you mind sharing your use-case in this scenario?

EDIT: Based on additional context provided, it seems like what you'd need is a pda for each user that tracks how much SOL they purchased, and a shared pda for all users that tracks how much SOL has been purchased in total. Then you wouldn't need to always store and update the equivalent token amount, as how much tokens a user is entitled do be dynamically calculated during the claim/distribution step using the information outlined above.

If there's multiple rounds of claim/distribution, you should also consider adjusting your program to take previously claimed tokens into account in your calculations to prevent a double-allocation.

Provided extra information
Source Link
Ademola
  • 3.9k
  • 3
  • 20

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle or hash-basedchain solution, but this might be expensive wrt compute). Do you mind sharing your use-case in this scenario?

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle-based solution). Do you mind sharing your use-case in this scenario?

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle or hash-chain solution, but this might be expensive wrt compute). Do you mind sharing your use-case in this scenario?

added 42 characters in body
Source Link
Ademola
  • 3.9k
  • 3
  • 20

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle-based solution). Do you mind sharing your use-case in this scenario?

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code. Do you mind sharing your use-case in this scenario?

If you really need to get the complete list of all users that liked the post on-chain, you might need to store all the pubkeys in a single account(i.e a likes(Vec<Pubkey>) field) and extend the account size if needed. You might need to keep track of the current capacity of the likes vector, or else calculate it dynamically from the account data's size whenever you need it. This is because Vec::capacity will always just return the size of the deserialized vector, essentially Vec::len.

Hence you'd just have to check for when capacity == length and then extend the account using the steps shown here.

An alternate way to keep track of the capacity is to always fill up uninitialized keys in likes with Pubkey::default so Vec::capacity gives the actual capacity. You'd then find and replace a default pubkey to insert an actual one, and know the capacity is filled up when there's no default to replace.

You can also just extend the account's size by 32 bytes for each like and make the user pay for their space. This would mean you don't need to track capacity as it's always used up.

P.S: I'm skeptical that you would need this information on-chain though. For most cases, the canonical way to handle stuff like this would be to use pdas, retrieve all pdas using the getProgramAccounts call on the client side, and only validate those accounts in your on-chain code(you might consider a merkle-based solution). Do you mind sharing your use-case in this scenario?

Source Link
Ademola
  • 3.9k
  • 3
  • 20
Loading