X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=pkg%2Fserver%2Fserver.go;h=8be10b2a0821577c1f50b7d448e34782644e16a5;hb=HEAD;hp=8f113328d144dec7d575d4bafa86be62fd126e3c;hpb=d24526e0d767f7b45956d362180d2684e1e17294;p=epoint diff --git a/pkg/server/server.go b/pkg/server/server.go index 8f11332..8be10b2 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -260,7 +260,7 @@ func addDraft(d []byte, signed *document.Signed, draft *document.Draft) (c []byt func addDebit(d []byte, signed *document.Signed, cert *document.DebitCert) (c []byte, err error) { w := new(work) w.docid = document.Id(signed) - w.account = fmt.Sprintf("%s.%s", cert.Holder, cert.Issuer) + w.account = fmt.Sprintf("%s.%s", cert.Beneficiary, cert.Issuer) w.in = d w.signed = signed w.debit = cert @@ -302,45 +302,41 @@ func dispatch() { func handle(w *work) { log.Printf("start work: %s", w.account) if w.debit != nil { - handleDebit(w) + w.out, w.err = handleDebit(w) } else if w.draft != nil { - handleDraft(w) + w.out, w.err = handleDraft(w) } else { panic("unreachable") } - log.Printf("finish work: %s outlen: %d, errtype: %T", w.account, len(w.out), w.err) + log.Printf("finish work: %s outlen: %d", w.account, len(w.out)) delchan <- w w.sync <- 0 } -func handleDraft(w *work) { +func handleDraft(w *work) (c []byte, err error) { nonce := fmt.Sprintf("%s.%s", w.account, w.draft.Nonce) oldid, err := db.Get("draftby/key.issuer.nonce", nonce) if err == nil { if string(oldid) != w.docid { - w.err = fmt.Errorf("draft nonce is not unique (see draft %s)", oldid) + err = fmt.Errorf("draft nonce is not unique (see draft %s)", oldid) } else { - w.out, w.err = GetCert("certby/draft", w.docid) + c, err = GetCert("certby/draft", w.docid) } return } else if _, ok := err.(store.NotFoundError); !ok { - w.err = err return } err = db.Begin(w.docid) if err != nil { - w.err = err return } err = db.Set("draft", w.docid, w.in) if err != nil { - w.err = err return } err = db.Set("draftby/key.issuer.nonce", nonce, []byte(w.docid)) if err != nil { - w.err = err return } cert, err := newDebitCert(w) @@ -353,7 +349,6 @@ func handleDraft(w *work) { if err != nil { return } - w.out = c certid := document.Id(signed) err = db.Set("cert", certid, c) if err != nil { @@ -381,24 +376,20 @@ func handleDraft(w *work) { return } -func handleDebit(w *work) { - c, err := GetCert("certby/debit", w.docid) +func handleDebit(w *work) (c []byte, err error) { + c, err = GetCert("certby/debit", w.docid) if err == nil { - w.out = c return } else if _, ok := err.(store.NotFoundError); !ok { // internal error - w.err = err return } err = db.Begin(w.docid) if err != nil { - w.err = err return } err = db.Set("cert", w.docid, w.in) if err != nil { - w.err = err return } // TODO: check pubkey etc @@ -412,7 +403,6 @@ func handleDebit(w *work) { // internal error return } - w.out = c certid := document.Id(signed) err = db.Set("cert", certid, c) if err != nil { @@ -439,6 +429,10 @@ func handleDebit(w *work) { return } +func isIssuer(c *document.Cert) bool { + return c.Issuer == c.Holder +} + func newDebitCert(w *work) (*document.DebitCert, error) { cert := new(document.DebitCert) cert.Holder = w.draft.Drawer @@ -471,6 +465,7 @@ func newDebitCert(w *work) (*document.DebitCert, error) { // internal error return nil, err } + // TODO: make sure oldcert and newcert cannot become inconsistent // TODO: this is a hack oldcert, err := document.ToCert(iv) if err != nil { @@ -483,8 +478,8 @@ func newDebitCert(w *work) (*document.DebitCert, error) { if cert.Balance <= -IntLimit { return nil, fmt.Errorf("balance limit exceeded: %d", cert.Balance) } - if oldcert.Balance > 0 && cert.Balance < 0 { - return nil, fmt.Errorf("insufficient funds: %d", oldcert.Balance) + if !isIssuer(&cert.Cert) && cert.Balance < 0 { + return nil, fmt.Errorf("insufficient funds: %d, draft: %d", oldcert.Balance, cert.Difference) } cert.LastDebitSerial = oldcert.LastDebitSerial cert.LastCreditSerial = oldcert.LastCreditSerial @@ -512,9 +507,13 @@ func newCreditCert(w *work) (*document.CreditCert, error) { cert.Drawer = w.debit.Holder cert.DebitCert = w.docid - oid, err := db.Get("certby/key", w.debit.Beneficiary) + oid, err := db.Get("certby/key.issuer", w.account) oldcertid := string(oid) if err != nil { + if _, ok := err.(store.NotFoundError); !ok { + // internal error + return nil, err + } // this is the first cert cert.Serial = 1 cert.Balance = cert.Difference @@ -542,6 +541,10 @@ func newCreditCert(w *work) (*document.CreditCert, error) { if cert.Balance >= IntLimit { return nil, fmt.Errorf("balance limit exceeded: %d", cert.Balance) } + // sanity check + if isIssuer(&cert.Cert) && cert.Balance > 0 { + return nil, fmt.Errorf("internal error") + } cert.LastDebitSerial = oldcert.LastDebitSerial cert.LastCreditSerial = oldcert.LastCreditSerial if _, ok := iv.(*document.DebitCert); ok {