Skip to content

Commit

Permalink
support sign keys
Browse files Browse the repository at this point in the history
  • Loading branch information
Liuhaai committed Dec 19, 2024
1 parent ddd26d1 commit 768a6a5
Show file tree
Hide file tree
Showing 15 changed files with 197 additions and 145 deletions.
3 changes: 2 additions & 1 deletion datasource/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ func (p *Clickhouse) Retrieve(taskIDs []common.Hash) ([]*task.Task, error) {

res = append(res, &task.Task{
ID: common.HexToHash(ts[i].TaskID),
Nonce: ts[i].Nonce,
ProjectID: pid,
ProjectVersion: ts[i].ProjectVersion,
Payload: []byte(ts[i].Payload),
DevicePubKey: pubkey,
Payload: []byte(ts[i].Payload),
Signature: sig,
})
}
Expand Down
18 changes: 11 additions & 7 deletions e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/iotexproject/w3bstream/e2e/services"
"github.com/iotexproject/w3bstream/project"
)

const (
Expand Down Expand Up @@ -80,7 +81,7 @@ func TestE2E(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tempApiNodeDB.Name())
defer tempApiNodeDB.Close()
apiNode, apiNodeUrl, err := apiNodeInit(chDSN, tempApiNodeDB.Name(), chainEndpoint, contracts.TaskManager, contracts.IoID)
apiNode, apiNodeUrl, err := apiNodeInit(chDSN, tempApiNodeDB.Name(), chainEndpoint, contracts)
require.NoError(t, err)
err = apiNode.Start()
require.NoError(t, err)
Expand Down Expand Up @@ -136,15 +137,16 @@ func TestE2E(t *testing.T) {
registerIoID(t, chainEndpoint, contracts, deviceKey, projectID)

t.Run("RISC0", func(t *testing.T) {
risc0ProjectFilePath := "./testdata/risc0"
t.Cleanup(func() {
if err := risc0VMContainer.Terminate(context.Background()); err != nil {
t.Logf("failed to terminate vm container: %v", err)
}
})
risc0CodePath := "./testdata/risc0.code"
project := &project.Project{Configs: []*project.Config{{Version: "v1", VMTypeID: 1}}}

// Upload project
uploadProject(t, chainEndpoint, ipfsEndpoint, risc0ProjectFilePath, contracts, projectOwnerKey, projectID, false)
uploadProject(t, chainEndpoint, ipfsEndpoint, project, &risc0CodePath, nil, contracts, projectOwnerKey, projectID, false)
require.NoError(t, err)

// Wait a few seconds for the device info synced on api node
Expand All @@ -165,19 +167,21 @@ func TestE2E(t *testing.T) {
dataJson, err := json.Marshal(msgData)
require.NoError(t, err)

sendMessage(t, dataJson, projectID, deviceKey, apiNodeUrl)
sendMessage(t, dataJson, projectID, nil, deviceKey, apiNodeUrl)

Check failure on line 170 in e2e/e2e_test.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

too many arguments in call to sendMessage
})

t.Run("GNARK", func(t *testing.T) {
gnarkProjectFilePath := "./testdata/gnark"
t.Cleanup(func() {
if err := gnarkVMContainer.Terminate(context.Background()); err != nil {
t.Logf("failed to terminate vm container: %v", err)
}
})
gnarkCodePath := "./testdata/gnark.code"
gnarkMetadataPath := "./testdata/gnark.metadata"
project := &project.Project{Configs: []*project.Config{{Version: "v1", VMTypeID: 5}}}

// Upload project
uploadProject(t, chainEndpoint, ipfsEndpoint, gnarkProjectFilePath, contracts, projectOwnerKey, projectID, true)
uploadProject(t, chainEndpoint, ipfsEndpoint, project, &gnarkCodePath, &gnarkMetadataPath, contracts, projectOwnerKey, projectID, true)
require.NoError(t, err)

// Wait a few seconds for the device info synced on api node
Expand All @@ -187,7 +191,7 @@ func TestE2E(t *testing.T) {
data, err := hex.DecodeString("00000001000000010000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001")
require.NoError(t, err)

sendMessage(t, data, projectID, deviceKey, apiNodeUrl)
sendMessage(t, data, projectID, nil, deviceKey, apiNodeUrl)

Check failure on line 194 in e2e/e2e_test.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

too many arguments in call to sendMessage
})
}

Expand Down
40 changes: 30 additions & 10 deletions e2e/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"fmt"
"log/slog"
"math/big"
"os"
"testing"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand All @@ -18,6 +17,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/iotexproject/w3bstream/e2e/services"
wsproject "github.com/iotexproject/w3bstream/project"
"github.com/iotexproject/w3bstream/service/apinode"
apinodeconfig "github.com/iotexproject/w3bstream/service/apinode/config"
apinodedb "github.com/iotexproject/w3bstream/service/apinode/db"
Expand All @@ -39,7 +39,7 @@ import (
"github.com/iotexproject/w3bstream/util/ipfs"
)

func apiNodeInit(chDSN, dbFile, chainEndpoint, taskManagerContractAddr, ioidContractAddr string) (*apinode.APINode, string, error) {
func apiNodeInit(chDSN, dbFile, chainEndpoint string, contractDeployments *services.ContractsDeployments) (*apinode.APINode, string, error) {
cfg := apinodeconfig.Config{
LogLevel: slog.LevelInfo,
ServiceEndpoint: ":9000",
Expand All @@ -50,8 +50,9 @@ func apiNodeInit(chDSN, dbFile, chainEndpoint, taskManagerContractAddr, ioidCont
PrvKey: "",
ChainEndpoint: chainEndpoint,
BeginningBlockNumber: 0,
TaskManagerContractAddr: taskManagerContractAddr,
IoIDContractAddr: ioidContractAddr,
ProjectContractAddr: contractDeployments.WSProject,
TaskManagerContractAddr: contractDeployments.TaskManager,
IoIDContractAddr: contractDeployments.IoID,
}

db, err := apinodedb.New(dbFile, chDSN)
Expand Down Expand Up @@ -197,7 +198,8 @@ func registerProject(t *testing.T, chainEndpoint string,
return newProjectID, nil
}

func uploadProject(t *testing.T, chainEndpoint, ipfsURL, projectFile string,
func uploadProject(t *testing.T, chainEndpoint, ipfsURL string,
proj *wsproject.Project, projCodePath *string, projMetadataPath *string,
contractDeployments *services.ContractsDeployments, projectOwner *ecdsa.PrivateKey, newProjectID *big.Int, pauseProject bool) {
client, err := ethclient.Dial(chainEndpoint)
require.NoError(t, err)
Expand All @@ -206,12 +208,26 @@ func uploadProject(t *testing.T, chainEndpoint, ipfsURL, projectFile string,

// Upload project file to IPFS and update project config
ipfs := ipfs.NewIPFS(ipfsURL)
content, err := os.ReadFile(projectFile)
if projCodePath != nil {
codeCID, err := ipfs.AddFile(*projCodePath)
require.NoError(t, err)
cgf, err := proj.DefaultConfig()
require.NoError(t, err)
cgf.Code = fileURL(ipfsURL, codeCID)
}
if projMetadataPath != nil {
metadataCID, err := ipfs.AddFile(*projMetadataPath)
require.NoError(t, err)
cgf, err := proj.DefaultConfig()
require.NoError(t, err)
cgf.Metadata = fileURL(ipfsURL, metadataCID)
}
projBytes, err := proj.Marshal()
projHash := sha256.Sum256(projBytes)
require.NoError(t, err)
hash256 := sha256.Sum256(content)
cid, err := ipfs.AddContent(content)
cid, err := ipfs.AddContent(projBytes)
require.NoError(t, err)
projectFileURL := fmt.Sprintf("ipfs://%s/%s", ipfsURL, cid)
projectFileURL := fileURL(ipfsURL, cid)
wsProject, err := project.NewProject(common.HexToAddress(contractDeployments.WSProject), client)
require.NoError(t, err)
tOpts, err := bind.NewKeyedTransactorWithChainID(projectOwner, chainID)
Expand All @@ -222,7 +238,7 @@ func uploadProject(t *testing.T, chainEndpoint, ipfsURL, projectFile string,
_, err = services.WaitForTransactionReceipt(client, tx.Hash())
require.NoError(t, err)
}
tx, err := wsProject.UpdateConfig(tOpts, newProjectID, projectFileURL, hash256)
tx, err := wsProject.UpdateConfig(tOpts, newProjectID, projectFileURL, projHash)
require.NoError(t, err)
_, err = services.WaitForTransactionReceipt(client, tx.Hash())
require.NoError(t, err)
Expand All @@ -232,6 +248,10 @@ func uploadProject(t *testing.T, chainEndpoint, ipfsURL, projectFile string,
require.NoError(t, err)
}

func fileURL(ipfsURL, cid string) string {
return fmt.Sprintf("ipfs://%s/%s", ipfsURL, cid)
}

func registerIoID(t *testing.T, chainEndpoint string,
contractDeployments *services.ContractsDeployments, device *ecdsa.PrivateKey, projectID *big.Int) {
client, err := ethclient.Dial(chainEndpoint)
Expand Down
2 changes: 1 addition & 1 deletion e2e/services/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func SetupRisc0VM() (*VMContainer, string, error) {
func SetupGnarkVM() (*VMContainer, string, error) {
ctx := context.Background()
req := testcontainers.ContainerRequest{
Image: "ghcr.io/iotexproject/gnarkserver:v0.0.17",
Image: "ghcr.io/iotexproject/gnarkserver:v0.0.20",
ExposedPorts: []string{"4005/tcp"},
WaitingFor: wait.ForListeningPort("4005"),
}
Expand Down
10 changes: 0 additions & 10 deletions e2e/testdata/gnark

This file was deleted.

Binary file added e2e/testdata/gnark.code
Binary file not shown.
Binary file added e2e/testdata/gnark.metadata
Binary file not shown.
10 changes: 0 additions & 10 deletions e2e/testdata/risc0

This file was deleted.

Binary file added e2e/testdata/risc0.code
Binary file not shown.
38 changes: 23 additions & 15 deletions e2e/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/ecdsa"
"crypto/sha256"
"encoding/binary"
"encoding/json"
"fmt"
"log"
Expand All @@ -19,13 +20,16 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/iotexproject/w3bstream/e2e/services"
"github.com/iotexproject/w3bstream/service/apinode/api"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"

"github.com/iotexproject/w3bstream/e2e/services"
"github.com/iotexproject/w3bstream/project"
"github.com/iotexproject/w3bstream/service/apinode/api"
)

func signMesssage(data []byte, projectID uint64, key *ecdsa.PrivateKey) ([]byte, error) {
func signMesssage(data []byte, projectID uint64, cfg *project.Config, key *ecdsa.PrivateKey) ([]byte, error) {
req := &api.CreateTaskReq{
Nonce: uint64(time.Now().Unix()),
ProjectID: strconv.Itoa(int(projectID)),
Expand All @@ -38,24 +42,28 @@ func signMesssage(data []byte, projectID uint64, key *ecdsa.PrivateKey) ([]byte,
}

h := sha256.Sum256(reqJson)
// TODO: uncomment once project config can be loaded
// value := gjson.GetBytes(data, "timestamp")
// buf := new(bytes.Buffer)
// if err := binary.Write(buf, binary.LittleEndian, value.Uint()); err != nil {
// return nil, errors.New("failed to convert uint64 to bytes array")
// }
// d := []byte{}
// d = append(d, h[:]...)
// d = append(d, buf.Bytes()...)
// nh := sha256.Sum256(d)

if cfg != nil && len(cfg.SignedKeys) > 0 && gjson.ValidBytes(data) {
buf := new(bytes.Buffer)
buf.Write(h[:])
for _, key := range cfg.SignedKeys {
switch key.Type {
case "uint64":
value := gjson.GetBytes(data, key.Name)
if err := binary.Write(buf, binary.LittleEndian, uint64(value.Uint())); err != nil {
return nil, errors.New("failed to convert uint64 to bytes array")
}
}
}
h = sha256.Sum256(buf.Bytes())
}

sig, err := crypto.Sign(h[:], key)
if err != nil {
return nil, err
}
sig = sig[:len(sig)-1]

fmt.Printf("signature: %s, hash: %s\n", hexutil.Encode(sig), hexutil.Encode(h[:]))

req.Signature = hexutil.Encode(sig)

return json.Marshal(req)
Expand Down
Loading

0 comments on commit 768a6a5

Please sign in to comment.