Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,15 @@ var _ bin.EncoderDecoder = &Message{}
// SetVersion sets the message version.
// This method forces the message to be encoded in the specified version.
// NOTE: if you set lookups, the version will default to V0.
func (m *Message) SetVersion(version MessageVersion) *Message {
func (m *Message) SetVersion(version MessageVersion) (*Message, error) {
// check if the version is valid
switch version {
case MessageVersionV0, MessageVersionLegacy:
default:
panic(fmt.Errorf("invalid message version: %d", version))
return nil, fmt.Errorf("invalid message version: %d", version)
}
m.version = version
return m
return m, nil
}

// GetVersion returns the message version.
Expand Down
3 changes: 1 addition & 2 deletions nativetypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,7 @@ func (t Data) String() string {
case EncodingBase64Zstd:
enc, err := zstdEncoderPool.Get(nil)
if err != nil {
// TODO: remove panic?
panic(err)
return fmt.Sprintf("<zstd encoder error: %v>", err)
}
defer zstdEncoderPool.Put(enc)
return base64.StdEncoding.EncodeToString(enc.EncodeAll(t.Content, nil))
Expand Down
6 changes: 3 additions & 3 deletions programs/address-lookup-table/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import (

var ProgramID solana.PublicKey = solana.AddressLookupTableProgramID

func SetProgramID(pubkey solana.PublicKey) {
func SetProgramID(pubkey solana.PublicKey) error {
ProgramID = pubkey
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "AddressLookupTable"

func init() {
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
solana.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const (
Expand Down
6 changes: 3 additions & 3 deletions programs/associated-token-account/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ import (

var ProgramID solana.PublicKey = solana.SPLAssociatedTokenAccountProgramID

func SetProgramID(pubkey solana.PublicKey) {
func SetProgramID(pubkey solana.PublicKey) error {
ProgramID = pubkey
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "AssociatedTokenAccount"

func init() {
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
solana.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const (
Expand Down
6 changes: 3 additions & 3 deletions programs/compute-budget/instruction.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ import (

var ProgramID ag_solanago.PublicKey = ag_solanago.ComputeBudget

func SetProgramID(pubkey ag_solanago.PublicKey) {
func SetProgramID(pubkey ag_solanago.PublicKey) error {
ProgramID = pubkey
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "ComputeBudget"

func init() {
if !ProgramID.IsZero() {
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
ag_solanago.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
}

Expand Down
6 changes: 3 additions & 3 deletions programs/memo/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ import (

var ProgramID = ag_solanago.MemoProgramID

func SetProgramID(pubkey ag_solanago.PublicKey) {
func SetProgramID(pubkey ag_solanago.PublicKey) error {
ProgramID = pubkey
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

func init() {
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
ag_solanago.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

type MemoInstruction struct {
Expand Down
6 changes: 3 additions & 3 deletions programs/stake/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ import (

var ProgramID solana.PublicKey = solana.StakeProgramID

func SetProgramID(pubkey solana.PublicKey) {
func SetProgramID(pubkey solana.PublicKey) error {
ProgramID = pubkey
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "Stake"

func init() {
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
solana.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const (
Expand Down
6 changes: 3 additions & 3 deletions programs/system/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ import (

var ProgramID ag_solanago.PublicKey = ag_solanago.SystemProgramID

func SetProgramID(pubkey ag_solanago.PublicKey) {
func SetProgramID(pubkey ag_solanago.PublicKey) error {
ProgramID = pubkey
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "System"

func init() {
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
ag_solanago.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const (
Expand Down
6 changes: 3 additions & 3 deletions programs/token-2022/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ const MAX_SIGNERS = 11

var ProgramID ag_solanago.PublicKey = ag_solanago.Token2022ProgramID

func SetProgramID(pubkey ag_solanago.PublicKey) {
func SetProgramID(pubkey ag_solanago.PublicKey) error {
ProgramID = pubkey
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "Token2022"

func init() {
if !ProgramID.IsZero() {
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
ag_solanago.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
}

Expand Down
6 changes: 3 additions & 3 deletions programs/token/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ const MAX_SIGNERS = 11

var ProgramID ag_solanago.PublicKey = ag_solanago.TokenProgramID

func SetProgramID(pubkey ag_solanago.PublicKey) {
func SetProgramID(pubkey ag_solanago.PublicKey) error {
ProgramID = pubkey
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "Token"

func init() {
if !ProgramID.IsZero() {
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
ag_solanago.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
}

Expand Down
2 changes: 1 addition & 1 deletion programs/tokenregistry/instruction.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
)

func init() {
solana.RegisterInstructionDecoder(ProgramID(), registryDecodeInstruction)
solana.MustRegisterInstructionDecoder(ProgramID(), registryDecodeInstruction)
}

func registryDecodeInstruction(accounts []*solana.AccountMeta, data []byte) (interface{}, error) {
Expand Down
6 changes: 3 additions & 3 deletions programs/vote/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ import (

var ProgramID solana.PublicKey = solana.VoteProgramID

func SetProgramID(pubkey solana.PublicKey) {
func SetProgramID(pubkey solana.PublicKey) error {
ProgramID = pubkey
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
return solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

const ProgramName = "Vote"

func init() {
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
solana.MustRegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}

type Instruction struct {
Expand Down
31 changes: 23 additions & 8 deletions registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,35 @@ func (reg *decoderRegistry) RegisterIfNew(programID PublicKey, decoder Instructi
return true
}

func RegisterInstructionDecoder(programID PublicKey, decoder InstructionDecoder) {
prev, has := instructionDecoderRegistry.Get(programID)
// RegisterInstructionDecoder registers a decoder for the given programID.
// Returns an error if a different decoder is already registered for that programID.
// Re-registering the same decoder function is a no-op.
func RegisterInstructionDecoder(programID PublicKey, decoder InstructionDecoder) error {
instructionDecoderRegistry.mu.Lock()
defer instructionDecoderRegistry.mu.Unlock()

prev, has := instructionDecoderRegistry.decoders[programID]
if has {
// If it's the same function, then OK (tollerate multiple calls with same params).
// If it's the same function, then OK (tolerate multiple calls with same params).
if isSameFunction(prev, decoder) {
return
return nil
}
// If it's another decoder for the same pubkey, then panic.
panic(fmt.Sprintf("unable to re-register instruction decoder for program %s", programID))
// If it's another decoder for the same pubkey, return error.
return fmt.Errorf("unable to re-register instruction decoder for program %s", programID)
}
instructionDecoderRegistry.RegisterIfNew(programID, decoder)
instructionDecoderRegistry.decoders[programID] = decoder
return nil
}

func isSameFunction(f1 interface{}, f2 interface{}) bool {
// MustRegisterInstructionDecoder is like RegisterInstructionDecoder but panics on error.
// Intended for use in init() functions where error handling is not possible.
func MustRegisterInstructionDecoder(programID PublicKey, decoder InstructionDecoder) {
if err := RegisterInstructionDecoder(programID, decoder); err != nil {
panic(err)
}
}

func isSameFunction(f1 any, f2 any) bool {
return reflect.ValueOf(f1).Pointer() == reflect.ValueOf(f2).Pointer()
}

Expand Down
22 changes: 11 additions & 11 deletions registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestRegisterInstructionDecoder(t *testing.T) {

decoder := func(instructionAccounts []*AccountMeta, data []byte) (interface{}, error) {
decoder := func(instructionAccounts []*AccountMeta, data []byte) (any, error) {
return nil, nil
}
decoderAnother := func(instructionAccounts []*AccountMeta, data []byte) (interface{}, error) {
decoderAnother := func(instructionAccounts []*AccountMeta, data []byte) (any, error) {
return nil, nil
}

assert.NotPanics(t, func() {
RegisterInstructionDecoder(BPFLoaderProgramID, decoder)
})
assert.NotPanics(t, func() {
RegisterInstructionDecoder(BPFLoaderProgramID, decoder)
})
assert.Panics(t, func() {
RegisterInstructionDecoder(BPFLoaderProgramID, decoderAnother)
})
// First registration succeeds.
require.NoError(t, RegisterInstructionDecoder(BPFLoaderProgramID, decoder))

// Re-registering the same decoder is a no-op.
require.NoError(t, RegisterInstructionDecoder(BPFLoaderProgramID, decoder))

// Registering a different decoder for the same programID returns an error.
assert.Error(t, RegisterInstructionDecoder(BPFLoaderProgramID, decoderAnother))
}
Loading