-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable ChainReader to read PDA account state #1003
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all looks great to me! Really readable and straightforward. Not sure if you're done adding functionality for CCIP but this should unblock the interface tests
)) | ||
var reader readBinding | ||
// Create PDA read binding if Seeds config is non-nil | ||
// Note: Empty seeds list is a valid configuration for a PDA so a length check is intentionally skipped |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would an empty seeds list just be a normal account read?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think FindProgramAddress
still outputs a different programID even with empty seeds since it's still applying the bump seed. I think every PDA in the on-chain code uses some sort of seed though. So guess it wouldn't hurt to also validate empty seeds for our current use case but I wanted to keep this open in case something changes in the future.
pkg/solana/codec/solana.go
Outdated
case SeedPubKey: | ||
typedCodec = NewPublicKey() | ||
case SeedUint64: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why can't we reuse asStruct here so that every type is handled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking asStruct
seemed strongly tied to IDL types and since PDA seeds aren't officially defined in the IDL I thought it made sense to keep this separate. But your comments making me rethink that. I think I can use IDLField
in place of SeedDefinition
and reuse the existing IDLType
instead of my custom enum. I'll give this a shot
pkg/solana/codec/solana.go
Outdated
var typedCodec commonencodings.TypeCodec | ||
switch field.Type { | ||
case SeedPubKey: | ||
typedCodec = NewPublicKey() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is special handling for public key needed? Why doesn't regular public key encoded by Solana codec work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry this was just a miss on my part. I see this now which would get automatically picked up once I address the previous comment.
} | ||
reader = newPdaReadBinding(namespace, genericName, readDefinition.PDAPrefix) | ||
} else { | ||
if err := s.addCodecDef(true, namespace, genericName, codec.ChainConfigTypeAccountDef, idl, codec.NilIdlTypeDefTy, readDefinition.InputModifications); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do? There are no inputs for non PDA account reads
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is unused for normal account reads. For encoding PDAs, we only really need the new addSeedsCodecDef
method I added. But when I tried to remove this, I started getting some errors. I can debug and see what's going on but since this was already in the existing code I opted to keep it as is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my bad actually, I wrote this code lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I left it as a placeholder for PDA to be input, not sure why it throws errors
func (s *SolanaChainReaderService) addSeedsCodecDef(namespace, genericName string, seedDefs []codec.SeedDefinition, modCfg commoncodec.ModifiersConfig) error { | ||
mod, err := modCfg.ToModifier(codec.DecoderHooks...) | ||
if err != nil { | ||
return err | ||
} | ||
// Append seed suffix to differentiate the entry for encoding seeds from the account read entry | ||
seedEntry, err := codec.NewSeedEntry(genericName, mod, seedDefs) | ||
if err != nil { | ||
return fmt.Errorf("failed to create a codec entry for seed definitions %v: %w", seedDefs, err) | ||
} | ||
|
||
// Seed codec entry is only used for encoding. Read type is not used by WrapItemType for encoding string. | ||
s.parsed.EncoderDefs[codec.WrapItemType(true, namespace, genericName, "")] = seedEntry | ||
|
||
return nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can go away in favour of just using addCodecDef()
. You just need to define seeds as a new IDL type and handle it like events, args and accounts are handled here CreateCodecEntry()
which is a func used by addCodecDef()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Quality Gate failedFailed conditions |
Enable the ChainReader to read PDA account state
PDADefintion
field to the read definition to allow us to configure the fields needed for a PDA account readPDADefintion
includes aPrefix
and aSeeds
fieldPrefix
is a static string that is converted to bytes and prepended to the list of seeds used for PDA calculationSeeds
is a list of seeds that are expected to be provided throughparams
accountReadBinding
'sGetAddress
method to intakeparams
to use for seeds when calculating the PDAaccountReadBinding
to encode and build the seeds list