153 lines
4.7 KiB
Go
153 lines
4.7 KiB
Go
|
|
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
|
||
|
|
}
|