forked from gagliardetto/solana-go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
instruction.go
160 lines (137 loc) · 4.62 KB
/
instruction.go
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright 2021 github.com/gagliardetto
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package computebudget
import (
"bytes"
"fmt"
ag_spew "github.com/davecgh/go-spew/spew"
ag_solanago "github.com/desperatee/solana-go"
ag_text "github.com/desperatee/solana-go/text"
ag_binary "github.com/gagliardetto/binary"
ag_treeout "github.com/gagliardetto/treeout"
)
var ProgramID ag_solanago.PublicKey = ag_solanago.ComputeBudget
func SetProgramID(pubkey ag_solanago.PublicKey) {
ProgramID = pubkey
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
const ProgramName = "ComputeBudget"
func init() {
if !ProgramID.IsZero() {
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
}
const (
// Deprecated
// after feature remove_deprecated_request_unit_ix::id() is activated
Instruction_RequestUnitsDeprecated uint8 = iota
// Request a specific transaction-wide program heap region size in bytes.
// The value requested must be a multiple of 1024. This new heap region
// size applies to each program executed in the transaction, including all
// calls to CPIs.
Instruction_RequestHeapFrame
// Set a specific compute unit limit that the transaction is allowed to consume.
Instruction_SetComputeUnitLimit
// Set a compute unit price in "micro-lamports" to pay a higher transaction
// fee for higher transaction prioritization.
Instruction_SetComputeUnitPrice
)
// InstructionIDToName returns the name of the instruction given its ID.
func InstructionIDToName(id uint8) string {
switch id {
case Instruction_RequestUnitsDeprecated:
return "RequestUnitsDeprecated"
case Instruction_RequestHeapFrame:
return "RequestHeapFrame"
case Instruction_SetComputeUnitLimit:
return "SetComputeUnitLimit"
case Instruction_SetComputeUnitPrice:
return "SetComputeUnitPrice"
default:
return ""
}
}
type Instruction struct {
ag_binary.BaseVariant
}
func (inst *Instruction) EncodeToTree(parent ag_treeout.Branches) {
if enToTree, ok := inst.Impl.(ag_text.EncodableToTree); ok {
enToTree.EncodeToTree(parent)
} else {
parent.Child(ag_spew.Sdump(inst))
}
}
var InstructionImplDef = ag_binary.NewVariantDefinition(
ag_binary.Uint8TypeIDEncoding,
[]ag_binary.VariantType{
{
"RequestUnitsDeprecated", (*RequestUnitsDeprecated)(nil),
},
{
"RequestHeapFrame", (*RequestHeapFrame)(nil),
},
{
"SetComputeUnitLimit", (*SetComputeUnitLimit)(nil),
},
{
"SetComputeUnitPrice", (*SetComputeUnitPrice)(nil),
},
},
)
func (inst *Instruction) ProgramID() ag_solanago.PublicKey {
return ProgramID
}
func (inst *Instruction) Accounts() (out []*ag_solanago.AccountMeta) {
return inst.Impl.(ag_solanago.AccountsGettable).GetAccounts()
}
func (inst *Instruction) Data() ([]byte, error) {
buf := new(bytes.Buffer)
if err := ag_binary.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 *ag_text.Encoder, option *ag_text.Option) error {
return encoder.Encode(inst.Impl, option)
}
func (inst *Instruction) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
return inst.BaseVariant.UnmarshalBinaryVariant(decoder, InstructionImplDef)
}
func (inst Instruction) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
err := encoder.WriteUint8(inst.TypeID.Uint8())
if err != nil {
return fmt.Errorf("unable to write variant type: %w", err)
}
return encoder.Encode(inst.Impl)
}
func registryDecodeInstruction(accounts []*ag_solanago.AccountMeta, data []byte) (interface{}, error) {
inst, err := DecodeInstruction(accounts, data)
if err != nil {
return nil, err
}
return inst, nil
}
func DecodeInstruction(accounts []*ag_solanago.AccountMeta, data []byte) (*Instruction, error) {
inst := new(Instruction)
if err := ag_binary.NewBinDecoder(data).Decode(inst); err != nil {
return nil, fmt.Errorf("unable to decode instruction: %w", err)
}
if v, ok := inst.Impl.(ag_solanago.AccountsSettable); ok {
err := v.SetAccounts(accounts)
if err != nil {
return nil, fmt.Errorf("unable to set accounts for instruction: %w", err)
}
}
return inst, nil
}