better difficulty

main
Bill Mill 2 years ago
parent 5ac47534f7
commit b9f9ee38e5
  1. 48
      server/main.go

@ -1,12 +1,10 @@
// https://github.com/robinsloan/spring-83-spec/blob/main/draft-20220609.md
// TODO:
// * wipe expired posts
// * add difficulty checking
// * check that the body contains a proper last-modified tag
// * implement peer sharing and receiving
// * display HTML safely, and in shadow DOMs
// * right now we just don't allow actual HTML, which is of course
// against the spirit of the thing
// * display HTML safely (strip javascript with sanitize API maybe?)
// * add /<key> to show a single board
package main
import (
@ -165,6 +163,17 @@ func (s *Spring83Server) boardCount() (int, error) {
return count, nil
}
func (s *Spring83Server) getDifficulty() (float64, uint64, error) {
count, err := s.boardCount()
if err != nil {
return 0, 0, err
}
difficultyFactor := math.Pow(float64(count)/10_000_000, 4)
keyThreshold := uint64(MAX_SIG * (1.0 - difficultyFactor))
return difficultyFactor, keyThreshold, nil
}
func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Spring-Version", "83")
@ -214,15 +223,14 @@ func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
// apply another check. The key, interpreted as a 256-bit number, must be
// less than a threshold defined by the server's difficulty factor:
if curBoard == nil {
count, err := s.boardCount()
difficultyFactor, keyThreshold, err := s.getDifficulty()
if err != nil {
log.Printf(err.Error())
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
difficultyFactor := math.Pow(float64(count)/10_000_000, 4)
w.Header().Add("Spring-Difficulty", fmt.Sprintf("%f", difficultyFactor))
keyThreshold := MAX_SIG * (1.0 - difficultyFactor)
// Using that difficulty factor, we can calculate the key threshold:
//
@ -231,7 +239,7 @@ func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
//
// The server must reject PUT requests for new keys that are not less
// than <an inscrutable gigantic number>
if binary.BigEndian.Uint64(key) >= uint64(keyThreshold) {
if binary.BigEndian.Uint64(key) >= keyThreshold {
if err != nil || len(key) != 32 {
// the spec doesn't specify the proper return value in this case
http.Error(w, "Key greater than threshold", http.StatusBadRequest)
@ -292,7 +300,6 @@ func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
if keyStr[58:60] != "ed" ||
(last4 != time.Now().Format("2006") &&
last4 != time.Now().AddDate(1, 0, 0).Format("2006")) {
log.Printf("%s %s %s", keyStr[58:60] == "ed", last4 == time.Now().Format("2006"), time.Now().Format("2006"))
http.Error(w, "Signature must end with edYYYY", http.StatusBadRequest)
return
}
@ -305,19 +312,6 @@ func (s *Spring83Server) publishBoard(w http.ResponseWriter, r *http.Request) {
return
}
// TODO:
// Additionally, if the server doesn't have any board
// stored for <key>, then it must apply another check. The
// key, interpreted as a 256-bit number, must be less than
// a threshold defined by the server's difficulty factor:
//
// MAX_SIG = (2**256 - 1) key_threshold = MAX_SIG * ( 1.0 -
// difficulty_factor)
//
// This check is not applied to keys for which the server
// already has a board stored. You can read more about the
// difficulty factor later in this document.
expiry := time.Now().AddDate(0, 0, 7).Format(time.RFC3339)
_, err = s.db.Exec(`
INSERT INTO boards (key, board, expiry)
@ -373,6 +367,7 @@ func (s *Spring83Server) loadBoards() ([]Board, error) {
return boards, nil
}
// for now, on loads to /, I'm just going to show all boards no matter what
func (s *Spring83Server) showBoard(w http.ResponseWriter, r *http.Request) {
boards, err := s.loadBoards()
if err != nil {
@ -381,6 +376,15 @@ func (s *Spring83Server) showBoard(w http.ResponseWriter, r *http.Request) {
return
}
difficultyFactor, _, err := s.getDifficulty()
if err != nil {
log.Printf(err.Error())
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
w.Header().Add("Spring-Difficulty", fmt.Sprintf("%f", difficultyFactor))
boardBytes, err := json.Marshal(boards)
if err != nil {
log.Printf(err.Error())

Loading…
Cancel
Save