updated difficulty algorithm

main
Bill Mill 2 years ago
parent 0f45ddad3e
commit dd3eb463cb
  1. 33
      server/main.go

@ -35,7 +35,7 @@ import (
_ "github.com/mattn/go-sqlite3"
)
const MAX_SIG = (1 << 256) - 1
const MAX_KEY_64 = (1 << 64) - 1
const MAX_BODY_SIZE = 2217
var (
@ -140,7 +140,7 @@ func (s *Spring83Server) getBoard(key string) (*Board, error) {
row := s.db.QueryRow(query, key)
var dbkey, board, creation, expiry string
err := row.Scan(&dbkey, &board, &expiry)
err := row.Scan(&dbkey, &board, &creation, &expiry)
if err != nil {
if err != sql.ErrNoRows {
return nil, err
@ -191,8 +191,16 @@ func (s *Spring83Server) getDifficulty() (float64, uint64, error) {
return 0, 0, err
}
// The calculation of the difficulty factor is not part of this specification, but here's an example formula that works well:
//
// difficulty_factor = ( num_boards_stored / max_boards )**4
//
// a threshold defined by the server's difficulty factor:
//
// MAX_KEY_64 = (2**64 - 1)
// key_64_threshold = round(MAX_KEY_64 * ( 1.0 - difficulty_factor))
difficultyFactor := math.Pow(float64(count)/10_000_000, 4)
keyThreshold := uint64(MAX_SIG * (1.0 - difficultyFactor))
keyThreshold := uint64(math.Round(MAX_KEY_64 * (1.0 - difficultyFactor)))
return difficultyFactor, keyThreshold, nil
}
@ -237,14 +245,16 @@ func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Spring-Difficulty", fmt.Sprintf("%f", difficultyFactor))
// Using that difficulty factor, we can calculate the key threshold:
// If the server doesn't yet have any board stored for the key, then it
// must apply an additional check. The key's first 16 hex characters,
// interpreted as a 64-bit number, must be less than a threshold
// defined by the server's difficulty factor:
//
// MAX_KEY = (2**256 - 1)
// key_threshold = MAX_KEY * (1.0 - 0.52) = <an inscrutable gigantic number>
// MAX_KEY_64 = (2**64 - 1)
// key_64_threshold = round(MAX_KEY_64 * ( 1.0 - difficulty_factor))
//
// The server must reject PUT requests for new keys that are not less
// than <an inscrutable gigantic number>
if binary.BigEndian.Uint64(key) >= keyThreshold {
// If the key fails this check, the server must reject the PUT request, returning 403 Forbidden.
if binary.BigEndian.Uint64(key[:8]) < keyThreshold {
if err != nil || len(key) != 32 {
http.Error(w, "Key greater than threshold", http.StatusForbidden)
return
@ -378,6 +388,7 @@ func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
}
expiry := time.Now().AddDate(0, 0, 7).Format(time.RFC3339)
bodyTimeISO := bodyTime.Format(time.RFC3339)
_, err = s.db.Exec(`
INSERT INTO boards (key, board, creation_datetime, expiry_datetime)
values(?, ?, ?, ?)
@ -385,7 +396,7 @@ func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
board=?,
creation_datetime=?,
expiry_datetime=?
`, keyStr, body, bodyTime, expiry, body, bodyTime, expiry)
`, keyStr, body, bodyTimeISO, expiry, body, bodyTimeISO, expiry)
if err != nil {
log.Printf("%s", err)
@ -414,7 +425,7 @@ func (s *Spring83Server) loadBoards() ([]Board, error) {
for rows.Next() {
var key, board, creation, expiry string
err = rows.Scan(&key, &board, &expiry)
err = rows.Scan(&key, &board, &creation, &expiry)
if err != nil {
return nil, err
}

Loading…
Cancel
Save