forked from solana-foundation/solana-go
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinstructions.go
More file actions
138 lines (115 loc) · 3.81 KB
/
instructions.go
File metadata and controls
138 lines (115 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package addresslookuptable
import (
"bytes"
"encoding/binary"
"fmt"
spew "github.com/davecgh/go-spew/spew"
bin "github.com/gagliardetto/binary"
solana "github.com/gagliardetto/solana-go"
text "github.com/gagliardetto/solana-go/text"
treeout "github.com/gagliardetto/treeout"
)
var ProgramID solana.PublicKey = solana.AddressLookupTableProgramID
func SetProgramID(pubkey solana.PublicKey) error {
ProgramID = pubkey
return solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
const ProgramName = "AddressLookupTable"
func init() {
solana.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
const (
// Create a new address lookup table.
Instruction_CreateLookupTable uint32 = iota
// Permanently freeze a lookup table, making it immutable.
Instruction_FreezeLookupTable
// Extend an address lookup table with new addresses.
Instruction_ExtendLookupTable
// Deactivate a lookup table, making it eligible for closing after a cooldown period.
Instruction_DeactivateLookupTable
// Close a deactivated lookup table and reclaim rent.
Instruction_CloseLookupTable
)
// InstructionIDToName returns the name of the instruction given its ID.
func InstructionIDToName(id uint32) string {
switch id {
case Instruction_CreateLookupTable:
return "CreateLookupTable"
case Instruction_FreezeLookupTable:
return "FreezeLookupTable"
case Instruction_ExtendLookupTable:
return "ExtendLookupTable"
case Instruction_DeactivateLookupTable:
return "DeactivateLookupTable"
case Instruction_CloseLookupTable:
return "CloseLookupTable"
default:
return ""
}
}
type Instruction struct {
bin.BaseVariant
}
func (inst *Instruction) EncodeToTree(parent treeout.Branches) {
if enToTree, ok := inst.Impl.(text.EncodableToTree); ok {
enToTree.EncodeToTree(parent)
} else {
parent.Child(spew.Sdump(inst))
}
}
var InstructionImplDef = bin.NewVariantDefinition(
bin.Uint32TypeIDEncoding,
[]bin.VariantType{
{"CreateLookupTable", (*CreateLookupTable)(nil)},
{"FreezeLookupTable", (*FreezeLookupTable)(nil)},
{"ExtendLookupTable", (*ExtendLookupTable)(nil)},
{"DeactivateLookupTable", (*DeactivateLookupTable)(nil)},
{"CloseLookupTable", (*CloseLookupTable)(nil)},
},
)
func (inst *Instruction) ProgramID() solana.PublicKey {
return ProgramID
}
func (inst *Instruction) Accounts() (out []*solana.AccountMeta) {
return inst.Impl.(solana.AccountsGettable).GetAccounts()
}
func (inst *Instruction) Data() ([]byte, error) {
buf := new(bytes.Buffer)
if err := bin.NewBinEncoder(buf).Encode(inst); err != nil {
return nil, fmt.Errorf("unable to encode instruction: %w", err)
}
return buf.Bytes(), nil
}
func (inst *Instruction) TextEncode(encoder *text.Encoder, option *text.Option) error {
return encoder.Encode(inst.Impl, option)
}
func (inst *Instruction) UnmarshalWithDecoder(decoder *bin.Decoder) error {
return inst.BaseVariant.UnmarshalBinaryVariant(decoder, InstructionImplDef)
}
func (inst Instruction) MarshalWithEncoder(encoder *bin.Encoder) error {
err := encoder.WriteUint32(inst.TypeID.Uint32(), binary.LittleEndian)
if err != nil {
return fmt.Errorf("unable to write variant type: %w", err)
}
return encoder.Encode(inst.Impl)
}
func registryDecodeInstruction(accounts []*solana.AccountMeta, data []byte) (interface{}, error) {
inst, err := DecodeInstruction(accounts, data)
if err != nil {
return nil, err
}
return inst, nil
}
func DecodeInstruction(accounts []*solana.AccountMeta, data []byte) (*Instruction, error) {
inst := new(Instruction)
if err := bin.NewBinDecoder(data).Decode(inst); err != nil {
return nil, fmt.Errorf("unable to decode instruction: %w", err)
}
if v, ok := inst.Impl.(solana.AccountsSettable); ok {
err := v.SetAccounts(accounts)
if err != nil {
return nil, fmt.Errorf("unable to set accounts for instruction: %w", err)
}
}
return inst, nil
}