Skip to content

Commit

Permalink
Fix lookup tables parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
gagliardetto committed Jun 25, 2023
1 parent 290a21a commit 8209f78
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions programs/address-lookup-table/address-lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import (
)

// The serialized size of lookup table metadata.
const LOOKUP_TABLE_META_SIZE = 56
const (
LOOKUP_TABLE_META_SIZE = 56
LOOKUP_TABLE_MAX_ADDRESSES = 256
)

// DecodeAddressLookupTableState decodes the given account bytes into a AddressLookupTableState.
func DecodeAddressLookupTableState(data []byte) (*AddressLookupTableState, error) {
Expand Down Expand Up @@ -68,37 +71,49 @@ func (a *AddressLookupTableState) UnmarshalWithDecoder(decoder *bin.Decoder) (er
return fmt.Errorf("failed to decode TypeIndex: %w", err)
}
if a.DeactivationSlot, err = decoder.ReadUint64(bin.LE); err != nil {
return err
return fmt.Errorf("failed to decode DeactivationSlot: %w", err)
}
if a.LastExtendedSlot, err = decoder.ReadUint64(bin.LE); err != nil {
return err
return fmt.Errorf("failed to decode LastExtendedSlot: %w", err)
}
if a.LastExtendedSlotStartIndex, err = decoder.ReadUint8(); err != nil {
return err
return fmt.Errorf("failed to decode LastExtendedSlotStartIndex: %w", err)
}
has, err := decoder.ReadBool()
has, err := decoder.ReadOption()
if err != nil {
return err
return fmt.Errorf("failed to decode Authority option: %w", err)
}
if has {
var auth solana.PublicKey
if _, err := decoder.Read(auth[:]); err != nil {
return err
return fmt.Errorf("failed to decode Authority: %w", err)
}
a.Authority = &auth
} else {
err = decoder.Discard(32)
if err != nil {
return err
return fmt.Errorf("failed to decode Authority: %w", err)
}
}
serializedAddressesLen := decoder.Len() - LOOKUP_TABLE_META_SIZE
numSerializedAddresses := serializedAddressesLen / 32
if serializedAddressesLen%32 != 0 {
serializedAddressesNumBytes := decoder.Len() - LOOKUP_TABLE_META_SIZE
if serializedAddressesNumBytes == 0 {
// No addresses (the lookup table is empty).
a.Addresses = make(solana.PublicKeySlice, 0)
return nil
}

numSerializedAddresses := serializedAddressesNumBytes / 32
if serializedAddressesNumBytes%32 != 0 {
return fmt.Errorf("lookup table is invalid")
}
if numSerializedAddresses > LOOKUP_TABLE_MAX_ADDRESSES {
return fmt.Errorf("lookup table is invalid: max addresses exceeded (%d > %d)", numSerializedAddresses, LOOKUP_TABLE_MAX_ADDRESSES)
}

decoder.SetPosition(decoder.Position() + 2)
// Set the position to the start of the serialized addresses.
if err := decoder.SetPosition(LOOKUP_TABLE_META_SIZE); err != nil {
return fmt.Errorf("failed to set position: %w", err)
}
a.Addresses = make(solana.PublicKeySlice, numSerializedAddresses)

for i := 0; i < numSerializedAddresses; i++ {
Expand Down Expand Up @@ -132,14 +147,14 @@ func (a AddressLookupTableState) MarshalWithEncoder(encoder *bin.Encoder) error
return err
}
if a.Authority != nil {
if err := encoder.WriteBool(true); err != nil {
if err := encoder.WriteOption(true); err != nil {
return err
}
if _, err := encoder.Write(a.Authority[:]); err != nil {
return err
}
} else {
if err := encoder.WriteBool(false); err != nil {
if err := encoder.WriteOption(false); err != nil {
return err
}
if _, err := encoder.Write(make([]byte, 32)); err != nil {
Expand Down

0 comments on commit 8209f78

Please sign in to comment.