Skip to content

Commit 9796472

Browse files
committed
Added documentation
1 parent 440094b commit 9796472

File tree

6 files changed

+81
-10
lines changed

6 files changed

+81
-10
lines changed

cmd/fred/README.md

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@ Based on the hardware in existence, it represents the minimum amount of time to
2424
## Auction protocol
2525
Each auction has an Auction ID parameter.
2626

27-
1. Submit
27+
1. **Submit**
2828
* The submit stage should take roughly `(b*t)/n` time. `n` should be greater than 1.
2929
* During the submit stage, users will submit timelock-encrypted orders with time parameter `t`.
30-
2. Commit
30+
2. **Commit**
3131
* The commit stage marks the end of the "Submit" stage.
3232
* During the commit stage, the exchange broadcasts a commitment to a set of encrypted orders.
3333
* These encrypted orders include an unsolved puzzle, ciphertext, intended auction, and a hash.
34-
3. Respond
34+
3. **Respond**
3535
* Users who receive the commitment before `b*t` send a signature on the commitment to the exchange.
3636
* If the exchange receives unanimous signatures before `b*t`, the exchange broadcasts these signatures.
3737
* If not all users signed off on the commitment, the entire auction is marked as invalid and must start over.
3838
* Users should sign during this period if they're confident that the exchange could not have possibly solved a single one of the puzzles in the commitment.
3939
* A single malicious user can halt the exchange during this step.
40-
4. Decrypt
40+
4. **Decrypt**
4141
* This stage starts once the exchange has solved a puzzle, and decrypted an order in the set it committed to.
4242
* This should happen after `b*t`.
4343
* The exchange signs this data.
@@ -55,10 +55,10 @@ Each auction has an Auction ID parameter.
5555
Then the exchange won't be able to sign an update to the data without revealing their private key.
5656
In this case the auction would have to be restarted.
5757
* In any case of an invalid auction, users don't need to pay attention to anything the exchange does that depends on the invalid auction.
58-
5. Match
58+
5. **Match**
5959
* The exchange matches the orders, and signs the outcome of the matching.
6060
* If the matching is incorrect, then it's incorrect and you can prove it.
61-
6. Execute
61+
6. **Execute**
6262
* The exchange facilitates the trades through whatever settlement it feels like.
6363
* Ideally this would be done through lightning atomic swaps, since proofs can be produced for an honest execution.
6464
* In the case of lightning atomic swaps, blame can't be assigned to the user or the exchange if either party refuses to execute the trade.
@@ -83,3 +83,22 @@ Users could do a proof of work on their message once the auction has started, an
8383
This would only be an issue if there is a large domain for proof of work.
8484
This will normally be the case, since the message will include a signature, and the signature will be variable, depending on R.
8585
This doesn't mean anyone can front-run, since the orders are still hidden and the exchange will be committing to taking a position if it commits to its own orders before a puzzle could have possibly been solved.
86+
87+
Stateless matching algorithms can be considered to be time independent.
88+
89+
### Stateful matching algorithms
90+
91+
We don't *have to* be stuck with only stateless matching algorithms.
92+
We can use a combination of known, stateful algorithms that have a time priority requirement, and a stateless matching algorithm to have a persistent orderbook.
93+
Every order in an auction must have the same time priority, so we can do the following steps to be compatible with a persistent orderbook:
94+
95+
1. Match in auction
96+
* Nothing is different here than in the **Match** section of the protocol.
97+
* Here, we must match according to a stateless matching algorithm.
98+
2. Drop unfilled onto orderbook
99+
* Here, we'll still be using a stateless matching algorithm, but only to settle "ties".
100+
* Unfilled orders get put on the order queue with the highest time priority so far.
101+
The sequence of auctions determines the time priority for orders on this orderbook.
102+
In the case that multiple orders can be filled, but those orders have the same time priority, a stateless algorithm is used.
103+
3. Match according to any matching algorithm
104+
* Now, since we can settle ties with a stateless algorithm, we can use a stateful matching algorithm with the persistent orderbook.

crypto/rsw/rswtimelock.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Package rsw is an implementation of Rivest-Shamir-Wagner timelock puzzles, from RSW96.
2+
// The puzzles are based on modular exponentiation, and this package provides an easy to use API for creating and solving these types of puzzles.
13
package rsw
24

35
import (

crypto/rsw/rswtimelock_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,36 @@ package rsw
33
import (
44
"bytes"
55
"fmt"
6+
"log"
67
"testing"
78
)
89

10+
// This is how you create a solvable RSW timelock puzzle.
11+
func ExampleTimelockRSW_SetupTimelockPuzzle() {
12+
// Allocate memory for key
13+
key := make([]byte, 32)
14+
// set key to be some bytes that we want to be the solution to the puzzle
15+
copy(key[:], []byte(fmt.Sprint("!!! secret < 32 bytes !!!")))
16+
// Create a new timelock. A timelock can be used to create puzzles for a key with a certain time.
17+
rswTimelock, err := New2048A2(key)
18+
if err != nil {
19+
log.Fatalf("Error creating a new timelock puzzle: %s", err)
20+
}
21+
22+
// set the time to be some big number
23+
t := uint64(1000000)
24+
25+
// Create the puzzle. Puzzles can be solved.
26+
puzzle, expectedAns, err := rswTimelock.SetupTimelockPuzzle(t)
27+
if err != nil {
28+
log.Fatalf("Error creating puzzle: %s", err)
29+
}
30+
31+
fmt.Printf("Puzzle nil? %t. Expected Answer: %s", puzzle == nil, string(expectedAns))
32+
// Puzzle nil? false. Expected Answer: !!! secret < 32 bytes !!!
33+
34+
}
35+
936
func createSolveTest2048A2(time uint64, t *testing.T) {
1037
key := make([]byte, 32)
1138
copy(key[:], []byte(fmt.Sprintf("opencxcreatesolve%d", time)))

crypto/timelock.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type Timelock interface {
66
SetupTimelockPuzzle(t uint64) (puzzle Puzzle, answer []byte, err error)
77
}
88

9-
// Puzzle is what can actually be solved. It should return the same time t
9+
// Puzzle is what can actually be solved. It should return the same answer that was the result of SetupTimelockPuzzle.
1010
type Puzzle interface {
1111
// Solve solves the puzzle and returns the answer, or fails
1212
Solve() (answer []byte, err error)

logging/logging.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Package logging provides utilities to easily set a universal log level, as well as intuitively set a log file.
12
package logging
23

34
// Log Levels:
@@ -24,18 +25,24 @@ import (
2425
type LogLevel int
2526

2627
const (
27-
LogLevelError LogLevel = 0
28+
// LogLevelError is the log level that prints Panics, Fatals, and Errors.
29+
LogLevelError LogLevel = 0
30+
// LogLevelWarning is the log level that prints Panics, Fatals, Errors, and Warnings.
2831
LogLevelWarning LogLevel = 1
29-
LogLevelInfo LogLevel = 2
30-
LogLevelDebug LogLevel = 3
32+
// LogLevelInfo is the log level that prints Panics, Fatals, Errors, Warnings, and Infos.
33+
LogLevelInfo LogLevel = 2
34+
// LogLevelDebug is the log level that prints Panics, Fatals, Errors, Warnings, Infos, and Debugs.
35+
LogLevelDebug LogLevel = 3
3136
)
3237

3338
var logLevel = LogLevelError // the default
3439

40+
// SetLogLevel sets the global log level
3541
func SetLogLevel(newLevel int) {
3642
logLevel = LogLevel(newLevel)
3743
}
3844

45+
// SetLogFile sets a file to write to in addition to standard output.
3946
func SetLogFile(logFile io.Writer) {
4047
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
4148
logOutput := io.MultiWriter(os.Stdout, logFile)
@@ -46,91 +53,106 @@ func getPrefix(level string) string {
4653
return fmt.Sprintf("[%s]", level)
4754
}
4855

56+
// Fatalln prints a message and a new line, then calls os.Exit(1).
4957
func Fatalln(args ...interface{}) {
5058
log.Fatalln(args...)
5159
}
5260

61+
// Fatalf prints a message with a formatting directive, then calls os.Exit(1).
5362
func Fatalf(format string, args ...interface{}) {
5463
log.Fatalf(format, args...)
5564
}
5665

66+
// Fatal prints a message, then calls os.Exit(1).
5767
func Fatal(args ...interface{}) {
5868
log.Fatal(args...)
5969
}
6070

71+
// Debugf prints debug logs with a formatting directive.
6172
func Debugf(format string, args ...interface{}) {
6273
if logLevel >= LogLevelDebug {
6374
log.Printf(fmt.Sprintf("%s %s", getPrefix("DEBUG"), format), args...)
6475
}
6576
}
6677

78+
// Infof prints info logs with a formatting directive.
6779
func Infof(format string, args ...interface{}) {
6880
if logLevel >= LogLevelInfo {
6981
log.Printf(fmt.Sprintf("%s %s", getPrefix("INFO"), format), args...)
7082
}
7183
}
7284

85+
// Warnf prints warning logs with a formatting directive.
7386
func Warnf(format string, args ...interface{}) {
7487
if logLevel >= LogLevelWarning {
7588
log.Printf(fmt.Sprintf("%s %s", getPrefix("WARN"), format), args...)
7689
}
7790
}
7891

92+
// Errorf prints error logs with a formatting directive.
7993
func Errorf(format string, args ...interface{}) {
8094
if logLevel >= LogLevelError {
8195
log.Printf(fmt.Sprintf("%s %s", getPrefix("ERROR"), format), args...)
8296
}
8397
}
8498

99+
// Debugln prints debug logs, followed by a new line.
85100
func Debugln(args ...interface{}) {
86101
if logLevel >= LogLevelDebug {
87102
args = append([]interface{}{getPrefix("DEBUG")}, args...)
88103
log.Println(args...)
89104
}
90105
}
91106

107+
// Infoln prints info logs, followed by a new line.
92108
func Infoln(args ...interface{}) {
93109
if logLevel >= LogLevelInfo {
94110
args = append([]interface{}{getPrefix("INFO")}, args...)
95111
log.Println(args...)
96112
}
97113
}
98114

115+
// Warnln prints warning logs, followed by a new line.
99116
func Warnln(args ...interface{}) {
100117
if logLevel >= LogLevelWarning {
101118
args = append([]interface{}{getPrefix("WARN")}, args...)
102119
log.Println(args...)
103120
}
104121
}
105122

123+
// Errorln prints error logs, followed by a new line.
106124
func Errorln(args ...interface{}) {
107125
if logLevel >= LogLevelError {
108126
args = append([]interface{}{getPrefix("ERROR")}, args...)
109127
log.Println(args...)
110128
}
111129
}
112130

131+
// Debug prints debug logs.
113132
func Debug(args ...interface{}) {
114133
if logLevel >= LogLevelDebug {
115134
args = append([]interface{}{getPrefix("DEBUG")}, args...)
116135
log.Print(args...)
117136
}
118137
}
119138

139+
// Info prints info logs.
120140
func Info(args ...interface{}) {
121141
if logLevel >= LogLevelInfo {
122142
args = append([]interface{}{getPrefix("INFO")}, args...)
123143
log.Print(args...)
124144
}
125145
}
126146

147+
// Warn prints warning logs.
127148
func Warn(args ...interface{}) {
128149
if logLevel >= LogLevelWarning {
129150
args = append([]interface{}{getPrefix("WARN")}, args...)
130151
log.Print(args...)
131152
}
132153
}
133154

155+
// Error prints error logs.
134156
func Error(args ...interface{}) {
135157
if logLevel >= LogLevelError {
136158
args = append([]interface{}{getPrefix("ERROR")}, args...)

match/consts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Package match provides utilities and useful structures for building exchange systems.
12
package match
23

34
import (

0 commit comments

Comments
 (0)