Skip to content

Commit

Permalink
support multi hash algorithm (#761)
Browse files Browse the repository at this point in the history
  • Loading branch information
huangzhiran authored Nov 25, 2024
1 parent 1130e61 commit d1dd439
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 27 deletions.
40 changes: 28 additions & 12 deletions service/apinode/api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api
import (
"bytes"
"crypto/ecdsa"
"crypto/sha256"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -32,11 +33,12 @@ func newErrResp(err error) *errResp {
}

type CreateTaskReq struct {
Nonce uint64 `json:"nonce" binding:"required"`
ProjectID uint64 `json:"projectID" binding:"required"`
ProjectVersion string `json:"projectVersion"`
Payloads []string `json:"payloads" binding:"required"`
Signature string `json:"signature,omitempty" binding:"required"`
Nonce uint64 `json:"nonce" binding:"required"`
ProjectID uint64 `json:"projectID" binding:"required"`
ProjectVersion string `json:"projectVersion,omitempty"`
Payloads []string `json:"payloads" binding:"required"`
HashAlgorithm string `json:"hashAlgorithm,omitempty"`
Signature string `json:"signature,omitempty" binding:"required"`
}

type CreateTaskResp struct {
Expand Down Expand Up @@ -79,7 +81,7 @@ func (s *httpServer) createTask(c *gin.Context) {
c.JSON(http.StatusBadRequest, newErrResp(errors.Wrap(err, "failed to decode signature from hex format")))
return
}
pubKey, err := recoverPubkey(*req, sig)
pubKey, hashAlg, err := recoverPubkey(*req, sig)
if err != nil {
slog.Error("failed to recover public key", "error", err)
c.JSON(http.StatusBadRequest, newErrResp(errors.Wrap(err, "invalid signature; could not recover public key")))
Expand Down Expand Up @@ -126,6 +128,7 @@ func (s *httpServer) createTask(c *gin.Context) {
ProjectVersion: req.ProjectVersion,
Payloads: payloadsJ,
Signature: sig,
HashAlgorithm: hashAlg,
},
); err != nil {
slog.Error("failed to create task to persistence layer", "error", err)
Expand Down Expand Up @@ -164,19 +167,32 @@ func (s *httpServer) createTask(c *gin.Context) {
})
}

func recoverPubkey(req CreateTaskReq, sig []byte) (*ecdsa.PublicKey, error) {
func recoverPubkey(req CreateTaskReq, sig []byte) (*ecdsa.PublicKey, string, error) {
req.Signature = ""
reqJson, err := json.Marshal(req)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal request into json format")
return nil, "", errors.Wrap(err, "failed to marshal request into json format")
}

h := crypto.Keccak256Hash(reqJson)
sigpk, err := crypto.SigToPub(h.Bytes(), sig)
var alg string
var h []byte

switch req.HashAlgorithm {
case "sha256":
hash := sha256.New()
hash.Write(reqJson)
h = hash.Sum(nil)
alg = "sha256"
default:
h = crypto.Keccak256Hash(reqJson).Bytes()
alg = "keccak256"
}

sigpk, err := crypto.SigToPub(h, sig)
if err != nil {
return nil, errors.Wrap(err, "failed to recover public key from signature")
return nil, "", errors.Wrap(err, "failed to recover public key from signature")
}
return sigpk, nil
return sigpk, alg, nil
}

func (s *httpServer) getProverTaskState(taskID string) (*StateLog, error) {
Expand Down
32 changes: 17 additions & 15 deletions service/apinode/db/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Task struct {
ProjectVersion string `ch:"project_version"`
Payloads []byte `ch:"payloads"`
Signature []byte `ch:"signature"`
HashAlgorithm string `ch:"hash_algorithm"`
CreatedAt time.Time `ch:"create_at"`
}

Expand All @@ -44,21 +45,22 @@ func (p *DB) FetchTask(taskID common.Hash) (*Task, error) {

func migrateCH(conn driver.Conn) error {
err := conn.Exec(context.Background(), `
CREATE TABLE IF NOT EXISTS w3bstream_tasks
(
task_id Array(UInt8) NOT NULL,
device_id Array(UInt8) NOT NULL,
nonce UInt64 NOT NULL,
project_id UInt64 NOT NULL,
project_version String NOT NULL,
payloads Array(UInt8) NOT NULL,
signature Array(UInt8) NOT NULL,
create_at DateTime NOT NULL
)
ENGINE = ReplacingMergeTree()
PRIMARY KEY task_id
ORDER BY task_id
`)
CREATE TABLE IF NOT EXISTS w3bstream_tasks
(
task_id Array(UInt8) NOT NULL,
device_id Array(UInt8) NOT NULL,
nonce UInt64 NOT NULL,
project_id UInt64 NOT NULL,
project_version String NOT NULL,
payloads Array(UInt8) NOT NULL,
signature Array(UInt8) NOT NULL,
hash_algorithm String NOT NULL,
create_at DateTime NOT NULL
)
ENGINE = ReplacingMergeTree()
PRIMARY KEY task_id
ORDER BY task_id`,
)
return errors.Wrap(err, "failed to create clickhouse table")
}

Expand Down

0 comments on commit d1dd439

Please sign in to comment.