func (db *T) PutTransaction(tx *transaction.Envelope) (e error) { writable(&e, db, func(dbtx *bolt.Tx) bool { bucket, e := dbtx.CreateBucketIfNotExists([]byte("transactions")) if e != nil { return false } encoded, e := tx.Encode() if e != nil { return false } e = bucket.Put(tx.Hash(), encoded) if e != nil { return false } return true }) return }
func NameRegistrar(srv *context.T) { log := srv.Log.New("cmp", "name") ch := srv.Router.Sub("/block/last") loop: select { case blki := <-ch: if blk, ok := blki.(*block.Block); ok { processPendingAllocations(srv, log) for i := range blk.Transactions { tx0 := blk.Transactions[i] tx := tx0.Transaction switch tx.(type) { case *transaction.NameAllocation: log.Debug("processing name allocation transaction", "txn", tx0) tx1 := tx.(*transaction.NameAllocation) // 1. find the reservation // 1.1. check if it was done with this server and there's a reference // in scrap records reservation, err := srv.DB.GetScrap(util.SHA256(append(tx1.Rand, []byte(tx1.Name)...))) var reservationTx *transaction.Envelope if reservation == nil || err != nil { // 1.2 no scrap found, so try searching throughout database curBlock, err := srv.DB.GetLastBlock() if err != nil { log.Error("can't find last block during name allocation attempt") break } for curBlock != nil { for i := range curBlock.Transactions { if isValidReservation(curBlock.Transactions[i], tx0) { reservationTx = curBlock.Transactions[i] } } h := curBlock.PreviousBlockHash curBlock, err = srv.DB.GetBlock(h) if err != nil { log.Error("can't find block during name allocation attempt", "txn", h, "err", err) break } } } else { blk, err := srv.DB.GetTransactionBlock(reservation) if err != nil { log.Error("can't find block for name reservation", "txn", reservationTx, "err", err) break } for i := range blk.Transactions { if isValidReservation(blk.Transactions[i], tx0) { reservationTx = blk.Transactions[i] break } } } if reservationTx == nil { log.Error("can't find corresponding name reservation for allocation", "txn", tx0) break } // 2. verify its maturity confirmations, err := srv.DB.GetTransactionConfirmations(reservationTx.Hash()) if err != nil { log.Error("can't compute number of confirmations for reservation", "txn", reservationTx.Hash(), "err", err) break } if confirmations >= RESERVATION_CONFIRMATIONS_REQUIRED { // this reservation is confirmed srv.DB.PutRepository(repository.NewRepository(tx1.Name, repository.PENDING, tx0.Hash())) log.Info("created pending repository", "repo", tx1.Name, "alloc_txn", tx0.Hash()) } else { // this allocation is wasted as the distance is not long enough } default: // ignore all other transactions } } } } goto loop }