예제 #1
0
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
}