Files
pump-parser/metaorapool_test.go

153 lines
4.7 KiB
Go
Raw Permalink Normal View History

2026-04-29 17:14:26 +08:00
package pump_parser
import (
"encoding/base64"
"encoding/binary"
"testing"
"github.com/gagliardetto/solana-go"
)
func TestMetaoraPoolSwapEventFromLogsUsesMatchingInvocation(t *testing.T) {
firstEvent := metaoraPoolSwapEventLogForTest(10, 9, 1, 0, 0)
secondEvent := metaoraPoolSwapEventLogForTest(4013522650, 135, 8043041, 2010760, 0)
logs := []string{
"Program " + metaoraPoolProgramID.String() + " invoke [1]",
"Program log: Instruction: Swap",
"Program data: " + firstEvent,
"Program " + metaoraPoolProgramID.String() + " success",
"Program " + solana.TokenProgramID.String() + " invoke [1]",
"Program data: " + secondEvent,
"Program " + solana.TokenProgramID.String() + " success",
"Program " + metaoraPoolProgramID.String() + " invoke [1]",
"Program log: Instruction: Swap",
"Program data: " + secondEvent,
"Program " + metaoraPoolProgramID.String() + " success",
}
event, ok := metaoraPoolSwapEventFromLogs(logs, 2)
if !ok {
t.Fatal("expected second swap event")
}
if event.InAmount != 4013522650 {
t.Fatalf("in amount = %d, want 4013522650", event.InAmount)
}
if event.OutAmount != 135 {
t.Fatalf("out amount = %d, want 135", event.OutAmount)
}
if event.TradeFee != 8043041 {
t.Fatalf("trade fee = %d, want 8043041", event.TradeFee)
}
if event.ProtocolFee != 2010760 {
t.Fatalf("protocol fee = %d, want 2010760", event.ProtocolFee)
}
}
func TestMetaoraPoolSwapInstructionOccurrenceIncludesInnerInstructions(t *testing.T) {
rawTx := &RawTx{
Transaction: Transaction{
Message: Message{
AccountKeys: solana.PublicKeySlice{
metaoraPoolProgramID,
solana.MustPublicKeyFromBase58("BASDaPs2cdVTsvgPRfESDLZgek8tKRTfqbR2ksdgptsn"),
},
Instructions: []Instruction{
{ProgramIDIndex: 0, Data: metaoraPoolSwapInstructionDataForTest()},
{ProgramIDIndex: 1, Data: []byte{1}},
},
},
},
Meta: Meta{
InnerInstructions: []InnerInstructions{
{
Index: 1,
Instructions: []Instruction{
{ProgramIDIndex: 0, Data: metaoraPoolSwapInstructionDataForTest()},
},
},
},
},
}
if got := metaoraPoolSwapInstructionOccurrence(rawTx, [2]uint{1, 1}); got != 2 {
t.Fatalf("occurrence = %d, want 2", got)
}
}
func TestAttachLogEventsToInstructions(t *testing.T) {
swapEvent := metaoraPoolSwapEventLogForTest(4013522650, 135, 8043041, 2010760, 0)
rawTx := &RawTx{
Transaction: Transaction{
Message: Message{
AccountKeys: solana.PublicKeySlice{
metaoraPoolProgramID,
solana.TokenProgramID,
},
Instructions: []Instruction{
{ProgramIDIndex: 0, Data: metaoraPoolSwapInstructionDataForTest()},
},
},
},
Meta: Meta{
InnerInstructions: []InnerInstructions{
{
Index: 0,
Instructions: []Instruction{
{ProgramIDIndex: 1, Data: []byte{3}, StackHeight: intPtrForTest(2)},
},
},
},
LogMessages: []string{
"Program " + metaoraPoolProgramID.String() + " invoke [1]",
"Program log: Instruction: Swap",
"Program " + solana.TokenProgramID.String() + " invoke [2]",
"Program " + solana.TokenProgramID.String() + " success",
"Program data: " + swapEvent,
"Program " + metaoraPoolProgramID.String() + " success",
},
},
}
applyRawTxConvertLogOptions(rawTx, RawTxConvertOptions{ParseLogEvents: true, IgnoreLogMessages: true})
if len(rawTx.Meta.LogMessages) != 0 {
t.Fatalf("log messages length = %d, want 0", len(rawTx.Meta.LogMessages))
}
if len(rawTx.Transaction.Message.Instructions[0].LogEvents) != 1 {
t.Fatalf("outer log events length = %d, want 1", len(rawTx.Transaction.Message.Instructions[0].LogEvents))
}
if len(rawTx.Meta.InnerInstructions[0].Instructions[0].LogEvents) != 0 {
t.Fatalf("inner log events length = %d, want 0", len(rawTx.Meta.InnerInstructions[0].Instructions[0].LogEvents))
}
event, ok := metaoraPoolSwapEventFromInstruction(rawTx.Transaction.Message.Instructions[0])
if !ok {
t.Fatal("expected swap event from outer instruction")
}
if event.OutAmount != 135 {
t.Fatalf("out amount = %d, want 135", event.OutAmount)
}
}
func metaoraPoolSwapInstructionDataForTest() []byte {
data := make([]byte, 8+16)
copy(data, metaoraPoolSwapDiscriminator[:])
return data
}
func metaoraPoolSwapEventLogForTest(inAmount, outAmount, tradeFee, protocolFee, hostFee uint64) string {
data := make([]byte, 8+40)
copy(data, metaoraPoolSwapEventDiscriminator[:])
binary.LittleEndian.PutUint64(data[8:16], inAmount)
binary.LittleEndian.PutUint64(data[16:24], outAmount)
binary.LittleEndian.PutUint64(data[24:32], tradeFee)
binary.LittleEndian.PutUint64(data[32:40], protocolFee)
binary.LittleEndian.PutUint64(data[40:48], hostFee)
return base64.StdEncoding.EncodeToString(data)
}
func intPtrForTest(value int) *int {
return &value
}