bmresearch / Solnet

Solana's .NET SDK and integration library.
https://blockmountain.io/Solnet
MIT License
324 stars 130 forks source link

[Bug] - Stack overflow when trying to add instruction systemprogram.transfer #198

Closed nukec closed 3 years ago

nukec commented 3 years ago

Describe the bug Transaction builder throws stack overflow:

Stack overflow. Repeat 9609 times:

at Solnet.Wallet.PublicKey.get_KeyBytes() at Solnet.Wallet.PublicKey.get_Key()

at Solnet.Rpc.Models.AccountMeta..ctor(Solnet.Wallet.PublicKey, Boolean, Boolean) at Solnet.Rpc.Models.AccountMeta.Writable(Solnet.Wallet.PublicKey, Boolean) at Solnet.Programs.TokenProgram.Transfer(Solnet.Wallet.PublicKey, Solnet.Wallet.PublicKey, UInt64, Solnet.Wallet.PublicKey, > System.Collections.Generic.IEnumerable`1)

To Reproduce Steps to reproduce the behavior: Simple transfer instruction

byte[] tx = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash)
                                                    .SetFeePayer(this._account)
                                                    .AddInstruction(TokenProgram.Transfer(source: this._account.PublicKey,
                                                                                          new PublicKey(publicKey),
                                                                                          amount: 25000,
                                                                                          authority: this._account.PublicKey))
                                                    .Build(new List<Account> { this._account });

Expected behavior Not throw stack overflow.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context Add any other context about the problem here.

tiago18c commented 3 years ago

Hello. I've looked into this and the only way this could happen is if you called the PublicKey(string) constructor with a null string.

Can you confirm if this was the case?

Either way, we will add some extra validation to PublicKey instantiation from string.

nukec commented 3 years ago

Two things. Passing null does cause stack overflow. Mistake #1. Another mistake is that I was trying to transfer lamports and not token, so I used wrong method TokenProgram.Transfer instead of SystemProgram.Transfer. Not sure how I didn't see this. But at least we found some validation around null could be beneficial.

tiago18c commented 3 years ago

I'm gonna leave this open until we add the null check. Thanks for reporting anyway :)

hoakbuilds commented 3 years ago

@nukec Null checks have been added on v0.4.5

Kremed commented 2 years ago

I am trying to send usdt Token, program address of USDT must be attached ??, or how can know which Token to send?? Are there clear examples and tests?

PublicKey FromAccount = new PublicKey(account.PublicKey);
PublicKey ToAccount = new PublicKey("CDQ3Gya9QermsPzU3cTNW9QPLbMVLbALQ2S8AwbruVJ");
PublicKey Auth = new PublicKey(account.PublicKey);
ulong UsdtAmount = 10;       
var LastBlockHash = await rpcClient.GetRecentBlockHashAsync();

byte[] tx = new TransactionBuilder().SetRecentBlockHash(LastBlockHash.Result.Value.Blockhash)
                                            .AddInstruction(TokenProgram.Transfer(FromAccount, 
                                                                                   ToAccount, 
                                                                                   UsdtAmount, 
                                                                                   Auth))
                                            .SetFeePayer(FromAccount)
                                            .Build(new List<Account> { wallet.Account }); 

var Response = await rpcClient.SendTransactionAsync(tx);
   if (!Response.WasSuccessful)
      {
          var a = Response.RawRpcResponse;
      }
      else
      {
            var a = Response.Result;
      }

Error : {"jsonrpc":"2.0","error":{"code":-32002,"message":"Transaction simulation failed: Error processing Instruction 0: invalid account data for instruction","data":{"accounts":null,"err":{"InstructionError":[0,"InvalidAccountData"]},"logs":["Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]","Program log: Instruction: Transfer","Program log: Error: InvalidAccountData","Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1294 of 200000 compute units","Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction"],"unitsConsumed":0}},"id":1}