github.com/gagliardetto/solana-go@v1.11.0/programs/compute-budget/instruction.go (about) 1 // Copyright 2021 github.com/gagliardetto 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package computebudget 16 17 import ( 18 "bytes" 19 "fmt" 20 21 ag_spew "github.com/davecgh/go-spew/spew" 22 ag_binary "github.com/gagliardetto/binary" 23 ag_solanago "github.com/gagliardetto/solana-go" 24 ag_text "github.com/gagliardetto/solana-go/text" 25 ag_treeout "github.com/gagliardetto/treeout" 26 ) 27 28 var ProgramID ag_solanago.PublicKey = ag_solanago.ComputeBudget 29 30 func SetProgramID(pubkey ag_solanago.PublicKey) { 31 ProgramID = pubkey 32 ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction) 33 } 34 35 const ProgramName = "ComputeBudget" 36 37 func init() { 38 if !ProgramID.IsZero() { 39 ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction) 40 } 41 } 42 43 const ( 44 // Deprecated 45 // after feature remove_deprecated_request_unit_ix::id() is activated 46 Instruction_RequestUnitsDeprecated uint8 = iota 47 48 // Request a specific transaction-wide program heap region size in bytes. 49 // The value requested must be a multiple of 1024. This new heap region 50 // size applies to each program executed in the transaction, including all 51 // calls to CPIs. 52 Instruction_RequestHeapFrame 53 54 // Set a specific compute unit limit that the transaction is allowed to consume. 55 Instruction_SetComputeUnitLimit 56 57 // Set a compute unit price in "micro-lamports" to pay a higher transaction 58 // fee for higher transaction prioritization. 59 Instruction_SetComputeUnitPrice 60 ) 61 62 // InstructionIDToName returns the name of the instruction given its ID. 63 func InstructionIDToName(id uint8) string { 64 switch id { 65 case Instruction_RequestUnitsDeprecated: 66 return "RequestUnitsDeprecated" 67 case Instruction_RequestHeapFrame: 68 return "RequestHeapFrame" 69 case Instruction_SetComputeUnitLimit: 70 return "SetComputeUnitLimit" 71 case Instruction_SetComputeUnitPrice: 72 return "SetComputeUnitPrice" 73 default: 74 return "" 75 } 76 } 77 78 type Instruction struct { 79 ag_binary.BaseVariant 80 } 81 82 func (inst *Instruction) EncodeToTree(parent ag_treeout.Branches) { 83 if enToTree, ok := inst.Impl.(ag_text.EncodableToTree); ok { 84 enToTree.EncodeToTree(parent) 85 } else { 86 parent.Child(ag_spew.Sdump(inst)) 87 } 88 } 89 90 var InstructionImplDef = ag_binary.NewVariantDefinition( 91 ag_binary.Uint8TypeIDEncoding, 92 []ag_binary.VariantType{ 93 { 94 "RequestUnitsDeprecated", (*RequestUnitsDeprecated)(nil), 95 }, 96 { 97 "RequestHeapFrame", (*RequestHeapFrame)(nil), 98 }, 99 { 100 "SetComputeUnitLimit", (*SetComputeUnitLimit)(nil), 101 }, 102 { 103 "SetComputeUnitPrice", (*SetComputeUnitPrice)(nil), 104 }, 105 }, 106 ) 107 108 func (inst *Instruction) ProgramID() ag_solanago.PublicKey { 109 return ProgramID 110 } 111 112 func (inst *Instruction) Accounts() (out []*ag_solanago.AccountMeta) { 113 return inst.Impl.(ag_solanago.AccountsGettable).GetAccounts() 114 } 115 116 func (inst *Instruction) Data() ([]byte, error) { 117 buf := new(bytes.Buffer) 118 if err := ag_binary.NewBinEncoder(buf).Encode(inst); err != nil { 119 return nil, fmt.Errorf("unable to encode instruction: %w", err) 120 } 121 return buf.Bytes(), nil 122 } 123 124 func (inst *Instruction) TextEncode(encoder *ag_text.Encoder, option *ag_text.Option) error { 125 return encoder.Encode(inst.Impl, option) 126 } 127 128 func (inst *Instruction) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error { 129 return inst.BaseVariant.UnmarshalBinaryVariant(decoder, InstructionImplDef) 130 } 131 132 func (inst Instruction) MarshalWithEncoder(encoder *ag_binary.Encoder) error { 133 err := encoder.WriteUint8(inst.TypeID.Uint8()) 134 if err != nil { 135 return fmt.Errorf("unable to write variant type: %w", err) 136 } 137 return encoder.Encode(inst.Impl) 138 } 139 140 func registryDecodeInstruction(accounts []*ag_solanago.AccountMeta, data []byte) (interface{}, error) { 141 inst, err := DecodeInstruction(accounts, data) 142 if err != nil { 143 return nil, err 144 } 145 return inst, nil 146 } 147 148 func DecodeInstruction(accounts []*ag_solanago.AccountMeta, data []byte) (*Instruction, error) { 149 inst := new(Instruction) 150 if err := ag_binary.NewBinDecoder(data).Decode(inst); err != nil { 151 return nil, fmt.Errorf("unable to decode instruction: %w", err) 152 } 153 if v, ok := inst.Impl.(ag_solanago.AccountsSettable); ok { 154 err := v.SetAccounts(accounts) 155 if err != nil { 156 return nil, fmt.Errorf("unable to set accounts for instruction: %w", err) 157 } 158 } 159 return inst, nil 160 }