Class: Solace::Accounts::AddressLookupTable

Inherits:
Object
  • Object
show all
Defined in:
lib/solace/accounts/address_lookup_table.rb

Overview

Models an on-chain Address Lookup Table account: its address, the metadata the program stores (authority, activation slots), and the full, ordered list of addresses it holds.

This is distinct from Solace::AddressLookupTable, which is the reference a v0 message carries (a table account plus the writable/readonly index positions into it). A composer decides which of this account's addresses load — a v0 concern that needs the account context — and this object owns the table-local part: turning the addresses it contributes into that message reference.

Examples:

Register a table on a composer

table = Solace::Accounts::AddressLookupTable.new(account: address, addresses: on_chain_addresses)
table.reference(loaded_writable, loaded_readonly) # => Solace::AddressLookupTable or nil

Read a table's on-chain state

data  = Base64.decode64(connection.(address)['data'][0])
table = Solace::Accounts::AddressLookupTable.deserialize(StringIO.new(data))
table.addresses # => the stored addresses

See Also:

Since:

  • 0.1.8

Constant Summary collapse

META_SIZE =

Byte offset at which the stored addresses begin — the program reserves a fixed-size metadata region ahead of them regardless of its contents.

Since:

  • 0.1.8

56

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(account: nil, addresses: nil, authority: nil, deactivation_slot: nil, last_extended_slot: nil) ⇒ AddressLookupTable

Initialize a lookup table account

Parameters:

  • account (#to_s, PublicKey, nil) (defaults to: nil)

    The lookup table's on-chain address

  • addresses (Array<#to_s>, nil) (defaults to: nil)

    The full, ordered address list; may be omitted (the composer then loads nothing through this table)

  • authority (String, nil) (defaults to: nil)

    The table authority

  • deactivation_slot (Integer, nil) (defaults to: nil)

    The deactivation slot

  • last_extended_slot (Integer, nil) (defaults to: nil)

    The last extended slot

Since:

  • 0.1.8



98
99
100
101
102
103
104
# File 'lib/solace/accounts/address_lookup_table.rb', line 98

def initialize(account: nil, addresses: nil, authority: nil, deactivation_slot: nil, last_extended_slot: nil)
  @account            = &.to_s
  @addresses          = Array(addresses).map(&:to_s)
  @authority          = authority
  @deactivation_slot  = deactivation_slot
  @last_extended_slot = last_extended_slot
end

Instance Attribute Details

#accountObject (readonly)

Since:

  • 0.1.8



38
39
40
# File 'lib/solace/accounts/address_lookup_table.rb', line 38

def 
  @account
end

#addressesObject (readonly)

Since:

  • 0.1.8



42
43
44
# File 'lib/solace/accounts/address_lookup_table.rb', line 42

def addresses
  @addresses
end

#authorityObject (readonly)

Since:

  • 0.1.8



46
47
48
# File 'lib/solace/accounts/address_lookup_table.rb', line 46

def authority
  @authority
end

#deactivation_slotObject (readonly)

Since:

  • 0.1.8



50
51
52
# File 'lib/solace/accounts/address_lookup_table.rb', line 50

def deactivation_slot
  @deactivation_slot
end

#last_extended_slotObject (readonly)

Since:

  • 0.1.8



54
55
56
# File 'lib/solace/accounts/address_lookup_table.rb', line 54

def last_extended_slot
  @last_extended_slot
end

Class Method Details

.deserialize(io) ⇒ AddressLookupTable

Deserialize an on-chain lookup table account

The BufferLayout is:

- [State type (4 bytes, u32 LE)]
- [Deactivation slot (8 bytes, u64 LE)]
- [Last extended slot (8 bytes, u64 LE)]
- [Last extended start index (1 byte)]
- [Authority (Borsh Option<Pubkey>)]
- [Padding, up to {META_SIZE}]
- [Addresses (32 bytes each, to end of data)]

Parameters:

  • io (IO, StringIO)

    The account data to read from

Returns:

Since:

  • 0.1.8



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/solace/accounts/address_lookup_table.rb', line 69

def self.deserialize(io)
  Utils::Codecs.decode_le_u32(io) # state type (1 = lookup table); positional
  deactivation_slot  = Utils::Codecs.decode_le_u64(io)
  last_extended_slot = Utils::Codecs.decode_le_u64(io)

  Utils::Codecs.decode_u8(io) # last extended start index; positional
  authority = Utils::Codecs.decode_option_pubkey(io)

  io.seek(META_SIZE) # addresses begin after the fixed-size metadata region

  addresses = []
  addresses << Utils::Codecs.decode_pubkey(io) until io.eof?

  new(
    deactivation_slot:  deactivation_slot,
    last_extended_slot: last_extended_slot,
    authority:          authority,
    addresses:          addresses
  )
end

Instance Method Details

#reference(writable, readonly) ⇒ Solace::AddressLookupTable?

Build the v0 message reference for the addresses this table contributes

Parameters:

  • writable (Array<String>)

    Loaded writable pubkeys drawn from this table

  • readonly (Array<String>)

    Loaded readonly pubkeys drawn from this table

Returns:

Since:

  • 0.1.8



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/solace/accounts/address_lookup_table.rb', line 111

def reference(writable, readonly)
  writable_indexes = positions_of(writable)
  readonly_indexes = positions_of(readonly)
  return if writable_indexes.empty? && readonly_indexes.empty?

  Solace::AddressLookupTable.new.tap do |reference|
    reference.          = 
    reference.writable_indexes = writable_indexes
    reference.readonly_indexes = readonly_indexes
  end
end