Decoder registry: don't panic if multiple calls with same parameters to `RegisterInstructionDecoder` func
This commit is contained in:
parent
7714a012fa
commit
4d4bc9a2f2
15
registry.go
15
registry.go
|
@ -20,6 +20,7 @@ package solana
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
@ -77,10 +78,20 @@ func (reg *decoderRegistry) RegisterIfNew(programID PublicKey, decoder Instructi
|
|||
}
|
||||
|
||||
func RegisterInstructionDecoder(programID PublicKey, decoder InstructionDecoder) {
|
||||
isNew := instructionDecoderRegistry.RegisterIfNew(programID, decoder)
|
||||
if !isNew {
|
||||
prev, has := instructionDecoderRegistry.Get(programID)
|
||||
if has {
|
||||
// If it's the same function, then OK (tollerate multiple calls with same params).
|
||||
if isSameFunction(prev, decoder) {
|
||||
return
|
||||
}
|
||||
// If it's another decoder for the same pubkey, then panic.
|
||||
panic(fmt.Sprintf("unable to re-register instruction decoder for program %s", programID))
|
||||
}
|
||||
instructionDecoderRegistry.RegisterIfNew(programID, decoder)
|
||||
}
|
||||
|
||||
func isSameFunction(f1 interface{}, f2 interface{}) bool {
|
||||
return reflect.ValueOf(f1).Pointer() == reflect.ValueOf(f2).Pointer()
|
||||
}
|
||||
|
||||
func DecodeInstruction(programID PublicKey, accounts []*AccountMeta, data []byte) (interface{}, error) {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package solana
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRegisterInstructionDecoder(t *testing.T) {
|
||||
|
||||
decoder := func(instructionAccounts []*AccountMeta, data []byte) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
decoderAnother := func(instructionAccounts []*AccountMeta, data []byte) (interface{}, 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)
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue