mv example to internal
This commit is contained in:
277
internal/example/geyser/error.go
Normal file
277
internal/example/geyser/error.go
Normal file
@@ -0,0 +1,277 @@
|
||||
package geyser
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type TransactionErrorVariant uint32
|
||||
type InstructionErrorVariant uint32
|
||||
|
||||
type InstructionErrorEnum struct {
|
||||
Index uint8
|
||||
Variant InstructionErrorVariant
|
||||
rest []byte
|
||||
}
|
||||
|
||||
type CustomInstructionErrorEnum struct {
|
||||
Code uint32
|
||||
}
|
||||
|
||||
const (
|
||||
AccountInUse TransactionErrorVariant = iota
|
||||
AccountLoadedTwice
|
||||
AccountNotFound
|
||||
ProgramAccountNotFound
|
||||
InsufficientFundsForFee
|
||||
InvalidAccountForFee
|
||||
AlreadyProcessed
|
||||
BlockhashNotFound
|
||||
|
||||
InstructionError //InstructionError(u8, InstructionError),
|
||||
|
||||
CallChainTooDeep
|
||||
MissingSignatureForFee
|
||||
InvalidAccountIndex
|
||||
SignatureFailure
|
||||
InvalidProgramForExecution
|
||||
SanitizeFailure
|
||||
ClusterMaintenance
|
||||
AccountBorrowOutstanding
|
||||
WouldExceedMaxBlockCostLimit
|
||||
UnsupportedVersion
|
||||
InvalidWritableAccount
|
||||
WouldExceedMaxAccountCostLimit
|
||||
WouldExceedAccountDataBlockLimit
|
||||
TooManyAccountLocks
|
||||
AddressLookupTableNotFound
|
||||
InvalidAddressLookupTableOwner
|
||||
InvalidAddressLookupTableData
|
||||
InvalidAddressLookupTableIndex
|
||||
InvalidRentPayingAccount
|
||||
WouldExceedMaxVoteCostLimit
|
||||
WouldExceedAccountDataTotalLimit
|
||||
|
||||
DuplicateInstruction //DuplicateInstruction(u8),
|
||||
|
||||
/*
|
||||
InsufficientFundsForRent {
|
||||
account_index: u8,
|
||||
},
|
||||
*/
|
||||
InsufficientFundsForRent
|
||||
|
||||
MaxLoadedAccountsDataSizeExceeded
|
||||
InvalidLoadedAccountsDataSizeLimit
|
||||
ResanitizationNeeded
|
||||
|
||||
/*
|
||||
ProgramExecutionTemporarilyRestricted {
|
||||
account_index: u8,
|
||||
},
|
||||
*/
|
||||
ProgramExecutionTemporarilyRestricted
|
||||
|
||||
UnbalancedTransaction
|
||||
ProgramCacheHitMaxLimit
|
||||
CommitCancelled
|
||||
)
|
||||
|
||||
const (
|
||||
GenericError InstructionErrorVariant = iota
|
||||
/// The arguments provided to a program were invalid
|
||||
InvalidArgument
|
||||
/// An instruction's data contents were invalid
|
||||
InvalidInstructionData
|
||||
/// An account's data contents was invalid
|
||||
InvalidAccountData
|
||||
/// An account's data was too small
|
||||
AccountDataTooSmall
|
||||
/// An account's balance was too small to complete the instruction
|
||||
InsufficientFunds
|
||||
/// The account did not have the expected program id
|
||||
IncorrectProgramId
|
||||
/// A signature was required but not found
|
||||
MissingRequiredSignature
|
||||
/// An initialize instruction was sent to an account that has already been initialized.
|
||||
AccountAlreadyInitialized
|
||||
/// An attempt to operate on an account that hasn't been initialized.
|
||||
UninitializedAccount
|
||||
/// Program's instruction lamport balance does not equal the balance after the instruction
|
||||
UnbalancedInstruction
|
||||
/// Program illegally modified an account's program id
|
||||
ModifiedProgramId
|
||||
/// Program spent the lamports of an account that doesn't belong to it
|
||||
ExternalAccountLamportSpend
|
||||
/// Program modified the data of an account that doesn't belong to it
|
||||
ExternalAccountDataModified
|
||||
/// Read-only account's lamports modified
|
||||
ReadonlyLamportChange
|
||||
/// Read-only account's data was modified
|
||||
ReadonlyDataModified
|
||||
/// An account was referenced more than once in a single instruction
|
||||
// Deprecated, instructions can now contain duplicate accounts
|
||||
DuplicateAccountIndex
|
||||
/// Executable bit on account changed, but shouldn't have
|
||||
ExecutableModified
|
||||
/// Rent_epoch account changed, but shouldn't have
|
||||
RentEpochModified
|
||||
/// The instruction expected additional account keys
|
||||
NotEnoughAccountKeys
|
||||
/// Program other than the account's owner changed the size of the account data
|
||||
AccountDataSizeChanged
|
||||
/// The instruction expected an executable account
|
||||
AccountNotExecutable
|
||||
/// Failed to borrow a reference to account data, already borrowed
|
||||
AccountBorrowFailed
|
||||
/// Account data has an outstanding reference after a program's execution
|
||||
InstructionAccountBorrowOutstanding
|
||||
/// The same account was multiply passed to an on-chain program's entrypoint, but the program
|
||||
/// modified them differently. A program can only modify one instance of the account because
|
||||
/// the runtime cannot determine which changes to pick or how to merge them if both are modified
|
||||
DuplicateAccountOutOfSync
|
||||
/// Allows on-chain programs to implement program-specific error types and see them returned
|
||||
/// by the Solana runtime. A program-specific error may be any type that is represented as
|
||||
/// or serialized to a u32 integer.
|
||||
|
||||
Custom // Custom(u32),
|
||||
|
||||
/// The return value from the program was invalid. Valid errors are either a defined builtin
|
||||
/// error value or a user-defined error in the lower 32 bits.
|
||||
InvalidError
|
||||
/// Executable account's data was modified
|
||||
ExecutableDataModified
|
||||
/// Executable account's lamports modified
|
||||
ExecutableLamportChange
|
||||
/// Executable accounts must be rent exempt
|
||||
ExecutableAccountNotRentExempt
|
||||
/// Unsupported program id
|
||||
UnsupportedProgramId
|
||||
/// Cross-program invocation call depth too deep
|
||||
CallDepth
|
||||
/// An account required by the instruction is missing
|
||||
MissingAccount
|
||||
/// Cross-program invocation reentrancy not allowed for this instruction
|
||||
ReentrancyNotAllowed
|
||||
/// Length of the seed is too long for address generation
|
||||
MaxSeedLengthExceeded
|
||||
/// Provided seeds do not result in a valid address
|
||||
InvalidSeeds
|
||||
/// Failed to reallocate account data of this length
|
||||
InvalidRealloc
|
||||
/// Computational budget exceeded
|
||||
ComputationalBudgetExceeded
|
||||
/// Cross-program invocation with unauthorized signer or writable account
|
||||
PrivilegeEscalation
|
||||
/// Failed to create program execution environment
|
||||
ProgramEnvironmentSetupFailure
|
||||
/// Program failed to complete
|
||||
ProgramFailedToComplete
|
||||
/// Program failed to compile
|
||||
ProgramFailedToCompile
|
||||
/// Account is immutable
|
||||
Immutable
|
||||
/// Incorrect authority provided
|
||||
IncorrectAuthority
|
||||
/// Failed to serialize or deserialize account data
|
||||
///
|
||||
/// Warning: This error should never be emitted by the runtime.
|
||||
///
|
||||
/// This error includes strings from the underlying 3rd party Borsh crate
|
||||
/// which can be dangerous because the error strings could change across
|
||||
/// Borsh versions. Only programs can use this error because they are
|
||||
/// consistent across Solana software versions.
|
||||
/// string values from this error should not be used in
|
||||
|
||||
BorshIoError // BorshIoError(String)
|
||||
|
||||
// An account does not have enough lamports to be rent-exempt
|
||||
AccountNotRentExempt
|
||||
/// Invalid account owner
|
||||
InvalidAccountOwner
|
||||
/// Program arithmetic overflowed
|
||||
ArithmeticOverflow
|
||||
/// Unsupported sysvar
|
||||
UnsupportedSysvar
|
||||
/// Illegal account owner
|
||||
IllegalOwner
|
||||
/// Accounts data allocations exceeded the maximum allowed per transaction
|
||||
MaxAccountsDataAllocationsExceeded
|
||||
/// Max accounts exceeded
|
||||
MaxAccountsExceeded
|
||||
/// Max instruction trace length exceeded
|
||||
MaxInstructionTraceLengthExceeded
|
||||
/// Builtin programs must consume compute units
|
||||
BuiltinProgramsMustConsumeComputeUnits
|
||||
)
|
||||
|
||||
type TransactionError struct {
|
||||
Variant TransactionErrorVariant
|
||||
rest []byte
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidTransactionError = errors.New("invalid transaction error")
|
||||
NotAnInstructionError = errors.New("not an instruction error")
|
||||
NotACustomInstructionError = errors.New("not a custom instruction error")
|
||||
UnsupportedInstructionError = errors.New("unsupported instruction error")
|
||||
)
|
||||
|
||||
func DecodeTransactionError(data []byte) (*TransactionError, error) {
|
||||
if len(data) < 4 {
|
||||
return nil, ErrInvalidTransactionError
|
||||
}
|
||||
|
||||
var err TransactionError
|
||||
variant := binary.LittleEndian.Uint32(data[:4])
|
||||
if variant > uint32(CommitCancelled) {
|
||||
return nil, UnsupportedInstructionError
|
||||
}
|
||||
err.Variant = TransactionErrorVariant(variant)
|
||||
err.rest = data[4:]
|
||||
|
||||
return &err, nil
|
||||
}
|
||||
|
||||
func (e *TransactionError) GetCustomErrorCode() (uint8, uint32, error) {
|
||||
instr, err := e.GetInstructionError()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
custom, err := instr.Custom()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return instr.Index, custom.Code, nil
|
||||
}
|
||||
|
||||
func (e *TransactionError) GetInstructionError() (*InstructionErrorEnum, error) {
|
||||
if e.Variant != InstructionError {
|
||||
return nil, NotAnInstructionError
|
||||
}
|
||||
if len(e.rest) < 5 {
|
||||
return nil, NotAnInstructionError
|
||||
}
|
||||
|
||||
var err InstructionErrorEnum
|
||||
err.Index = e.rest[0]
|
||||
variant := binary.LittleEndian.Uint32(e.rest[1:5])
|
||||
if variant > uint32(BuiltinProgramsMustConsumeComputeUnits) {
|
||||
return nil, UnsupportedInstructionError
|
||||
}
|
||||
err.Variant = InstructionErrorVariant(binary.LittleEndian.Uint32(e.rest[1:5]))
|
||||
err.rest = e.rest[5:]
|
||||
return &err, nil
|
||||
}
|
||||
|
||||
func (e *InstructionErrorEnum) Custom() (*CustomInstructionErrorEnum, error) {
|
||||
if e.Variant != Custom {
|
||||
return nil, NotACustomInstructionError
|
||||
}
|
||||
if len(e.rest) < 4 {
|
||||
return nil, NotACustomInstructionError
|
||||
}
|
||||
var custom CustomInstructionErrorEnum
|
||||
custom.Code = binary.LittleEndian.Uint32(e.rest[:4])
|
||||
return &custom, nil
|
||||
}
|
||||
Reference in New Issue
Block a user