X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=pkg%2Fserver%2Fserver.go;h=0271155f406f85438856993a59ec12c7ff5ea6d9;hb=e3a33b9736e993b64c2b869df13878da565e2986;hp=2a04bb8cb8140c8a44f866bca9ab3d812c98f314;hpb=3c9dfcb9ddc4190663a27c8dd6c2d9e1a5e4c897;p=epoint diff --git a/pkg/server/server.go b/pkg/server/server.go index 2a04bb8..0271155 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -9,6 +9,7 @@ import ( "epoint/key" "epoint/store" "fmt" + "log" "time" ) @@ -32,7 +33,7 @@ type work struct { var db *store.Conn var serverkey *openpgp.Entity var newchan chan *work -var delchan chan string +var delchan chan *work type worklist struct { head *work @@ -61,17 +62,21 @@ func popwork(ws *worklist) *work { return w } -func storekey() (err error) { - b := new(bytes.Buffer) - err = serverkey.Serialize(b) +func setserverkey(e *openpgp.Entity) (err error) { + serverkey = e + err = key.SelfSign(e) if err != nil { return } - err = db.Set("key", key.Id(serverkey), b.Bytes()) + d, err := key.Format(e) if err != nil { return } - err = db.Set("", "serverkey", b.Bytes()) + err = db.Set("key", key.Id(e), d) + if err != nil { + return + } + err = db.Set("", "serverkey", d) return } @@ -246,6 +251,7 @@ func addDraft(d []byte, signed *document.Signed, draft *document.Draft) (c []byt w.signed = signed w.draft = draft w.sync = make(chan int) + log.Printf("add draft work: %s", w.account) newchan <- w <-w.sync return w.out, w.err @@ -254,21 +260,24 @@ 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 w.sync = make(chan int) + log.Printf("add debit work: %s", w.account) newchan <- w <-w.sync return w.out, w.err } func dispatch() { + log.Printf("start dispatch") works := make(map[string]*worklist) for { select { case w := <-newchan: + log.Printf("queue work: %s", w.account) ws := works[w.account] if ws == nil { // TODO: unnecessary alloc @@ -277,58 +286,57 @@ func dispatch() { } else { pushwork(ws, w) } - case account := <-delchan: - ws := works[account] - w := popwork(ws) - if w == nil { - delete(works, account) + case w := <-delchan: + log.Printf("unqueue work: %s", w.account) + ws := works[w.account] + wnext := popwork(ws) + if wnext == nil { + delete(works, w.account) } else { - go handle(w) + go handle(wnext) } } } } 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") } - delchan <- w.account + log.Printf("finish work: %s outlen: %d, errtype: %T", w.account, len(w.out), w.err) + 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) @@ -342,7 +350,6 @@ func handleDraft(w *work) { return } certid := document.Id(signed) - w.out = c err = db.Set("cert", certid, c) if err != nil { // internal error @@ -369,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 @@ -499,9 +502,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 @@ -586,11 +593,12 @@ func Init(rootdir string, sk *openpgp.Entity) (err error) { if err != nil { return } - serverkey = sk - err = storekey() + err = setserverkey(sk) if err != nil { return } + newchan = make(chan *work) + delchan = make(chan *work) go dispatch() return }