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  }