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 }
func serveInternal(workerManager *client.WorkerManager, exit chan<- error) { mux := http.NewServeMux() s := &http.Server{ Addr: fmt.Sprintf("%v:%v", InternalIface, InternalPort), Handler: mux, // No timeouts! } relay := NewHttpRelay("/", protocol.BitwrkUrl, protocol.NewClient(&http.Transport{})) mux.Handle("/account/", relay) mux.Handle("/bid/", relay) mux.Handle("/deposit/", relay) mux.Handle("/tx/", relay) mux.Handle("/motd", relay) accountFilter := func(data []byte) ([]byte, error) { var account bitwrk.ParticipantAccount if err := json.Unmarshal(data, &account); err != nil { return data, nil } else { // Pass data about validation results into the template so it doesn't // have to be done in JavaScript. type result struct { Account bitwrk.ParticipantAccount Updated time.Time TrustedAccount string DepositAddress string DepositAddressValid bool } r := result{account, time.Now(), TrustedAccount, "", false} if v, err := url.ParseQuery(account.DepositInfo); err == nil { m := bitwrk.DepositAddressMessage{} m.FromValues(v) if m.VerifyWith(TrustedAccount) == nil { r.DepositAddress = m.DepositAddress r.DepositAddressValid = true } } return json.Marshal(r) } } myAccountUrl := fmt.Sprintf("%saccount/%s", protocol.BitwrkUrl, BitcoinIdentity.GetAddress()) myAccountRelay := NewHttpRelay("/myaccount", myAccountUrl, relay.client).WithFilterFunc(accountFilter) mux.Handle("/myaccount", myAccountRelay) resource := http.FileServer(http.Dir(path.Join(ResourceDir, "htroot"))) mux.Handle("/js/", resource) mux.Handle("/css/", resource) mux.Handle("/img/", resource) mux.HandleFunc("/buy/", handleBuy) mux.HandleFunc("/file/", handleFile) mux.HandleFunc("/", handleHome) mux.HandleFunc("/ui/", handleHome) mux.HandleFunc("/activities", handleActivities) if ExternalPort > 0 { mux.HandleFunc("/registerworker", func(w http.ResponseWriter, r *http.Request) { handleRegisterWorker(workerManager, w, r) }) } else { mux.HandleFunc("/registerworker", http.NotFound) } mux.HandleFunc("/unregisterworker", func(w http.ResponseWriter, r *http.Request) { handleUnregisterWorker(workerManager, w, r) }) mux.HandleFunc("/workers", func(w http.ResponseWriter, r *http.Request) { handleWorkers(workerManager, w, r) }) mux.HandleFunc("/mandates", func(w http.ResponseWriter, r *http.Request) { handleMandates(client.GetActivityManager(), w, r) }) mux.HandleFunc("/revokemandate", func(w http.ResponseWriter, r *http.Request) { if err := handleRevokeMandate(r); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }) mux.HandleFunc("/requestdepositaddress", func(w http.ResponseWriter, r *http.Request) { if err := handleRequestDepositAddress(r); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } else { // Account information is now stale myAccountRelay.InvalidateCache() } }) mux.HandleFunc("/id", handleId) mux.HandleFunc("/version", handleVersion) mux.HandleFunc("/cafsdebug", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html") client.GetActivityManager().GetStorage().DumpStatistics(cafs.NewWriterPrinter(w)) }) mux.HandleFunc("/stackdump", func(w http.ResponseWriter, r *http.Request) { name := r.FormValue("name") if len(name) == 0 { name = "goroutine" } profile := pprof.Lookup(name) if profile == nil { w.Write([]byte("No such profile")) return } err := profile.WriteTo(w, 1) if err != nil { log.Printf("Error in profile.WriteTo: %v\n", err) } }) exit <- s.ListenAndServe() }