func storeDepositInfo(c appengine.Context, r *http.Request, participant string) (err error) { // Important: checking (and invalidating) the nonce must be the first thing we do! err = checkNonce(c, r.FormValue("nonce")) if CfgRequireValidNonce && err != nil { return fmt.Errorf("Error in checkNonce: %v", err) } m := bitwrk.DepositAddressMessage{} m.FromValues(r.Form) if m.Participant != participant { return fmt.Errorf("Participant must be %#v", participant) } if m.Signer != CfgTrustedAccount { return fmt.Errorf("Signer must be %#v", CfgTrustedAccount) } // Bitcoin addresses must have the right network id if err := checkBitcoinAddress(m.DepositAddress); err != nil { return err } // Verify that the message was indeed signed by the trusted account if CfgRequireValidSignature { if err := m.VerifyWith(CfgTrustedAccount); err != nil { return err } } f := func(c appengine.Context) error { dao := db.NewGaeAccountingDao(c, true) if account, err := dao.GetAccount(participant); err != nil { return err } else { if account.DepositInfo != "" { c.Infof("Replacing old deposit info: %v", account.DepositInfo) } v := url.Values{} m.ToValues(v) account.DepositInfo = v.Encode() account.LastDepositInfo = time.Now() account.DepositAddressRequest = "" c.Infof("New deposit info: %v", account.DepositInfo) if err := dao.SaveAccount(&account); err != nil { return err } } return dao.Flush() } if err := datastore.RunInTransaction(c, f, &datastore.TransactionOptions{XG: true}); err != nil { // Transaction failed c.Errorf("Transaction failed: %v", err) return err } return }