File size: 2,787 Bytes
3b70664
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
(in-package #:nekod.socket)

;;; Deterministic receipts for every socket operation through the pipeline

(defstruct receipt
  (timestamp 0 :type integer)
  (socket-path-hash "" :type string)
  (request-method "" :type string)
  (request-path "" :type string)
  (request-hash "" :type string)
  (response-status 0 :type integer)
  (response-hash "" :type string)
  (event-class nil :type list)
  (router-input-hash "" :type string)
  (selected-experts nil :type list)
  (expert-weights nil :type list)
  (policy-decision "" :type string))

(defun sxhash-string (str)
  "Deterministic hash of string for receipt."
  (format nil "~16,'0x" (sxhash str)))

(defun hash-octets (octets)
  "Deterministic hash of octet vector for receipt."
  (format nil "~16,'0x" (sxhash (coerce octets 'list))))

(defun make-operation-receipt (&key method path request-body
                                    response-status response-body
                                    socket-path event-classes
                                    feature-vector experts weights
                                    policy)
  "Create a receipt for a complete pipeline operation."
  (make-receipt
   :timestamp (get-universal-time)
   :socket-path-hash (sxhash-string (or socket-path ""))
   :request-method (or method "")
   :request-path (or path "")
   :request-hash (sxhash-string (or request-body ""))
   :response-status (or response-status 0)
   :response-hash (if response-body
                      (if (stringp response-body)
                          (sxhash-string response-body)
                          (hash-octets response-body))
                      "")
   :event-class (or event-classes nil)
   :router-input-hash (if feature-vector
                          (sxhash-string (format nil "~a" (coerce feature-vector 'list)))
                          "")
   :selected-experts (or experts nil)
   :expert-weights (or weights nil)
   :policy-decision (or policy "ALLOW")))

(defun receipt-to-alist (r)
  "Convert receipt to alist for serialization."
  (list (cons :timestamp (receipt-timestamp r))
        (cons :socket-path-hash (receipt-socket-path-hash r))
        (cons :request-method (receipt-request-method r))
        (cons :request-path (receipt-request-path r))
        (cons :request-hash (receipt-request-hash r))
        (cons :response-status (receipt-response-status r))
        (cons :response-hash (receipt-response-hash r))
        (cons :event-class (receipt-event-class r))
        (cons :router-input-hash (receipt-router-input-hash r))
        (cons :selected-experts (receipt-selected-experts r))
        (cons :expert-weights (receipt-expert-weights r))
        (cons :policy-decision (receipt-policy-decision r))))