Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

send transaction success,but can not locate transaction on blockchain #212

Open
BillInUK opened this issue May 16, 2024 · 1 comment
Open

Comments

@BillInUK
Copy link

Hello, I have encountered a bug that occurs probabilistically. I want to send a transaction containing multiple instructions to the blockchain. Although I can successfully call

txSig, err := rpcClient.SendTransaction(context.Background(), tx)

and get a transaction ID, I sometimes find that the transaction is dropped by the Solana cluster when I search for it on the blockchain. What could be the reason?

The instructions in my transaction include:

  • Compute Budget: SetComputeUnitPrice
  • Compute Budget: SetComputeUnitLimit
  • Token Program: TransferChecked
  • Token Program: TransferChecked
  • System Program: Transfer

Here is my code:

func TestMultiInstructionTransfer(t *testing.T) {
	rpcClient := rpc.New(RpcUrl)

	rewardPrivKey := solana.MustPrivateKeyFromBase58(MainPrivate)
	alicePrivateKey := solana.MustPrivateKeyFromBase58(AlicePrivate)
	rewardPubKey := rewardPrivKey.PublicKey()
	alicePubKey := solana.MustPublicKeyFromBase58(AliceNativePubKey)
	bobPubKey := solana.MustPublicKeyFromBase58(BobNativePubKey)
	dexPubKey, _ := solana.PublicKeyFromBase58(DexNativePubKey)

	// get token account
	tokenMintAccount := solana.MustPublicKeyFromBase58(TokenMintAddress)
	rewardTokenAccount, err := GetSPLTokenAccountByNative(rpcClient, rewardPubKey, tokenMintAccount)
	if err != nil {
		panic(err)
	}
	fmt.Printf("get reward token account %v \n", rewardTokenAccount)

	aliceTokenAccount, err := GetSPLTokenAccountByNative(rpcClient, alicePubKey, tokenMintAccount)
	if err != nil {
		panic(err)
	}
	fmt.Printf("get to token account of alice %v \n", aliceTokenAccount)

	bobTokenAccount, err := GetSPLTokenAccountByNative(rpcClient, bobPubKey, tokenMintAccount)
	if err != nil {
		panic(err)
	}
	fmt.Printf("get to token account of bob %v \n", bobTokenAccount)

	amount := uint64(1100000)
	rewardAmount := uint64(1100000) * 2
	// ComputeBudget111111111111111111111111111111
	computeBudgetPriceInst := computebudget.NewSetComputeUnitPriceInstructionBuilder().
		SetMicroLamports(100000).
		Build()

	// ComputeBudget111111111111111111111111111111
	computeBudgetLimitInst := computebudget.NewSetComputeUnitLimitInstructionBuilder().
		SetUnits(600000).
		Build()

	// 添加多条指令
	// 1.transfer token to bob
	transferInst := token.NewTransferCheckedInstructionBuilder().
		SetAmount(amount).
		SetDecimals(6).
		SetSourceAccount(*aliceTokenAccount).
		SetMintAccount(tokenMintAccount).
		SetDestinationAccount(*bobTokenAccount).
		SetOwnerAccount(alicePubKey).
		Build()

	// 2.reward token to alice
	rewardInst := token.NewTransferCheckedInstructionBuilder().
		SetAmount(rewardAmount).
		SetDecimals(6).
		SetSourceAccount(*rewardTokenAccount).
		SetMintAccount(tokenMintAccount).
		SetDestinationAccount(*aliceTokenAccount).
		SetOwnerAccount(rewardPubKey).
		Build()

	// 3.send sol to dex
	toDexInst := system.NewTransferInstructionBuilder().
		SetLamports(2250000).
		SetFundingAccount(alicePubKey).
		SetRecipientAccount(dexPubKey).
		Build()

	// get recent block hash
	recent, err := rpcClient.GetRecentBlockhash(context.Background(), rpc.CommitmentFinalized)
	if err != nil {
		panic(err)
	}
	fmt.Printf("recent block hash is %v\n", recent.Value.Blockhash)

	// construct a transaction to estimate gas fee
	tx0, err := solana.NewTransaction(
		[]solana.Instruction{
			computeBudgetPriceInst,
			computeBudgetLimitInst,
			transferInst,
			rewardInst,
			toDexInst,
		},
		recent.Value.Blockhash,
		solana.TransactionPayer(alicePubKey),
	)
	if err != nil {
		panic(err)
	}

	messageContent0, err := tx0.Message.MarshalBinary()
	if err != nil {
		panic(err)
	}
	base64EncodeMsg := base64.StdEncoding.EncodeToString(messageContent0)

	feeResult, err := rpcClient.GetFeeForMessage(context.Background(), base64EncodeMsg, rpc.CommitmentConfirmed)
	if err != nil {
		panic(err)
	}
	fmt.Printf("get message fee %v\n", *feeResult.Value)

	// send gas fee & 2 to dex
	toDexInst = system.NewTransferInstructionBuilder().
		SetLamports(*feeResult.Value * 2).
		SetFundingAccount(alicePubKey).
		SetRecipientAccount(dexPubKey).
		Build()

	// construct the final transaction to send to blockchain
	tx, err := solana.NewTransaction(
		[]solana.Instruction{
			computeBudgetPriceInst,
			computeBudgetLimitInst,
			transferInst,
			rewardInst,
			toDexInst,
		},
		recent.Value.Blockhash,
		solana.TransactionPayer(alicePubKey),
	)
	if err != nil {
		panic(err)
	}

	// sign transaction
	_, err = tx.Sign(
		func(key solana.PublicKey) *solana.PrivateKey {
			if key.Equals(alicePubKey) {
				return &alicePrivateKey
			}
			if key.Equals(rewardPubKey) {
				return &rewardPrivKey
			}
			return nil
		})
	if err != nil {
		panic(err)
	}

	// get transaction sig and print it
	txSig, err := rpcClient.SendTransaction(context.Background(), tx)
	fmt.Printf("https://solscan.io/tx/%s\n", txSig)

}
@BillInUK
Copy link
Author

txSig, err := rpcClient.SendTransaction(context.Background(), tx)

always return success,but somtimes,transaction can not located at blockchain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant