manuelmauro/algonaut

Signature validation failed on 0 ALGO payment

dariost opened this issue · 2 comments

Describe the bug
When making a payment of 0 ALGO the transaction always fails for signature validation failed.

To Reproduce
Modify the payment example to have a transaction of 0 MicroAlgos:

diff --git a/examples/payment.rs b/examples/payment.rs
index d1a643e..cbb2ba6 100644
--- a/examples/payment.rs
+++ b/examples/payment.rs
@@ -23,7 +23,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
 
     let t = TxnBuilder::with(
         params,
-        Pay::new(from.address(), to.address(), MicroAlgos(123_456)).build(),
+        Pay::new(from.address(), to.address(), MicroAlgos(0)).build(),
     )
     .build();

When the example is run, this is the result I get:

$ ALGOD_URL="https://testnet.algoexplorerapi.io/" ALGOD_TOKEN="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" cargo run --example payment
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
     Running `/tmp/algonaut/target/debug/examples/payment`
response: Err(Request(RequestError { url: Some("https://testnet.algoexplorerapi.io/v2/transactions"), details: Http { status: 400, message: "transaction {_struct:{} Sig:[159 69 199 102 205 5 228 188 220 224 167 132 46 112 72 78 216 211 237 218 59 205 31 140 3 33 176 250 114 165 244 105 17 149 200 84 148 43 47 125 121 37 11 58 201 52 166 74 87 192 222 255 255 65 39 190 203 60 194 129 54 241 144 12] Msig:{_struct:{} Version:0 Threshold:0 Subsigs:[]} Lsig:{_struct:{} Logic:[] Sig:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] Msig:{_struct:{} Version:0 Threshold:0 Subsigs:[]} Args:[]} Txn:{_struct:{} Type:pay Header:{_struct:{} Sender:GIZTTA56FAJNAN7ACK3T6YG34FH32ETDULBZ6ENC4UV7EEHPXJGGSPCMVU Fee:{Raw:1000} FirstValid:15841715 LastValid:15842715 Note:[] GenesisID:testnet-v1.0 GenesisHash:JBR3KGFEWPEE5SAQ6IWU6EEBZMHXD4CZU6WCBXWGF57XBZIJHIRA Group:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Lease:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] RekeyTo:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ} KeyregTxnFields:{_struct:{} VotePK:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] SelectionPK:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] VoteFirst:0 VoteLast:0 VoteKeyDilution:0 Nonparticipation:false} PaymentTxnFields:{_struct:{} Receiver:BFRTECKTOOE7A5LHCF3TTEOH2A7BW46IYT2SX5VP6ANKEXHZYJY77SJTVM Amount:{Raw:0} CloseRemainderTo:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ} AssetConfigTxnFields:{_struct:{} ConfigAsset:0 AssetParams:{_struct:{} Total:0 Decimals:0 DefaultFrozen:false UnitName: AssetName: URL: MetadataHash:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] Manager:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ Reserve:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ Freeze:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ Clawback:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ}} AssetTransferTxnFields:{_struct:{} XferAsset:0 AssetAmount:0 AssetSender:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ AssetReceiver:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ AssetCloseTo:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ} AssetFreezeTxnFields:{_struct:{} FreezeAccount:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ FreezeAsset:0 AssetFrozen:false} ApplicationCallTxnFields:{_struct:{} ApplicationID:0 OnCompletion:NoOpOC ApplicationArgs:[] Accounts:[] ForeignApps:[] ForeignAssets:[] LocalStateSchema:{_struct:{} NumUint:0 NumByteSlice:0} GlobalStateSchema:{_struct:{} NumUint:0 NumByteSlice:0} ApprovalProgram:[] ClearStateProgram:[] ExtraProgramPages:0} CompactCertTxnFields:{_struct:{} CertRound:0 CertType:0 Cert:{_struct:{} SigCommit:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA SignedWeight:0 SigProofs:[] PartProofs:[] Reveals:map[]}}} AuthAddr:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ} invalid : signature validation failed" } }))

Expected behavior
Algonaut should produce a valid signature, since other SDKs (I tried with py-algorand-sdk) do.

The same problem also occurs if one of the fees in an atomic transactions group is 0.

If the atomic_swap.rs example is changed in the following way:

diff --git a/examples/atomic_swap.rs b/examples/atomic_swap.rs
index 5a7c7d4..6ffd0af 100644
--- a/examples/atomic_swap.rs
+++ b/examples/atomic_swap.rs
@@ -21,19 +21,25 @@ async fn main() -> Result<(), Box<dyn Error>> {
     let account1 = Account::from_mnemonic("fire enlist diesel stamp nuclear chunk student stumble call snow flock brush example slab guide choice option recall south kangaroo hundred matrix school above zero")?;
     let account2 = Account::from_mnemonic("since during average anxiety protect cherry club long lawsuit loan expand embark forum theory winter park twenty ball kangaroo cram burst board host ability left")?;
 
-    let params = algod.suggested_transaction_params().await?;
+    let mut params1 = algod.suggested_transaction_params().await?;
+    let mut params2 = params1.clone();
+
+    params1.fee = params1.fee + params2.fee;
+    params1.min_fee = params1.min_fee + params2.min_fee;
+    params2.fee = MicroAlgos(0);
+    params2.min_fee = MicroAlgos(0);
 
     // To keep the example short and as self-contained as possible, both transactions send Algos.
     // Normally you'll want to submit e.g. a payment and asset transfer or asset transfers for different assets.
 
     let t1 = &mut TxnBuilder::with(
-        params.clone(),
+        params1,
         Pay::new(account1.address(), account2.address(), MicroAlgos(1_000)).build(),
     )
     .build();
 
     let t2 = &mut TxnBuilder::with(
-        params,
+        params2,
         Pay::new(account2.address(), account1.address(), MicroAlgos(3_000)).build(),
     )
     .build();

it should still work due to the pooled fees feature of Algorand, however it fails with the same signature validation failed error.

Fixed on main!