0

I have the following case:

let contract = Invoice {
  origin: from.clone(),
  to: to.clone(),
  amount,
  status: false,
  id: 17,
  msg: msg.clone(),
};

let mut invoice_vec: Vec<Invoice<T::AccountId, T::AccountId, BalanceOf<T>>> = Vec::new();
invoice_vec.push(contract);


// Save in storage the sender and the invoices
<InvoiceSender<T>>::insert(from.clone(), &invoice_vec);

InvoiceSender::<T>::mutate(&from, |invoice| {
  invoice_vec.iter_mut().filter(|i| i.id == 17).for_each(|i| {
    i.status = true;
  })
});

As you can see, I have created an Invoice object, I have put it inside an array and then I have stored it.

The issue happens when I try to mutate one of the contracts.

During debugging I can see that the following line i.status = true; is being executed, but the status is remains false, so the state was not mutated.

2
  • You are mutating it to false and the contract.status is set to false, so yes the status is still false Commented Dec 13, 2022 at 13:17
  • It was a lapsus. I changed it to true.
    – P.E
    Commented Dec 13, 2022 at 13:23

1 Answer 1

0

There a couple of things I don't understand. If you have a StorageMap<AccountId, Vec<Invoice>>, when calling mutate, you need to use the |invoice| from the closure. You are modifying the outer vector invoice_vec, which is not persisted, it's just a temporary variable.

Does this solve it?

InvoiceSender::<T>::mutate(&from, |invoice| {
    invoice.iter_mut().filter(|i| i.id == 17).for_each(|i| { // <-- This line changed
        i.status = true;
    })
});

I'm not sure if you are trying to modify all the possible invoices of the user or just that one, but if you want to modify all the invoices that have id==17:

UPDATE: I've tested it locally using its repository, it just changes the status of the invoice, nothing else

if let Some(mut invoices_recevier) = Self::invoice_receiver(&to) {
    for invoice in &mut invoices_recevier {
        if invoice.id == id {
            invoice.status = true;
        }
    }
    InvoiceReceiver::<T>::insert(to.clone(), invoices_recevier);

    //...

    return Ok(());
}
4
  • I would like to edit only one with id 17 and if status is false
    – P.E
    Commented Dec 13, 2022 at 15:07
  • Still does not work :/
    – P.E
    Commented Dec 13, 2022 at 17:23
  • Where did you find the invoice for this method? InvoiceSender::<T>::mutate(&from, |invoice| { invoice.iter_mut().filter(|i| i.id == 17).for_each(|i| { // <-- This line changed i.status = true; }) });
    – P.E
    Commented Dec 13, 2022 at 19:00
  • Line 209 is the method which needs to be fixed: github.com/herou/EscrowPallet/blob/invoice_system/pallets/…
    – P.E
    Commented Dec 13, 2022 at 19:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.