diff --git a/.gitignore b/.gitignore index d4d1ff8f..85ef8d18 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,5 @@ docker/pgadmin node_trace.* internal/bin bin -conf.*.private +**/conf.*.private .idea diff --git a/.golangci.yml b/.golangci.yml index 15249f27..f0674989 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -121,7 +121,6 @@ linters-settings: tenv: all: true - linters: disable-all: true enable: @@ -146,7 +145,7 @@ linters: - forbidigo - funlen - gocheckcompilerdirectives -# - gochecknoinits + - gochecknoinits - gocognit - goconst - gocritic @@ -173,7 +172,7 @@ linters: - predeclared - promlinter - reassign -# - revive + - revive - rowserrcheck - sqlclosecheck - stylecheck @@ -203,6 +202,7 @@ issues: linters: - funlen - forbidigo + - gochecknoinits - path: "ent" linters: - gomnd diff --git a/Makefile b/Makefile index a096e465..3b28cf73 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,22 @@ prod: - GOOS=windows GOARCH=amd64 go build -o bin/unchained.windows.amd64.exe main.go - GOOS=darwin GOARCH=amd64 go build -o bin/unchained.darwin.amd64 main.go - GOOS=linux GOARCH=amd64 go build -o bin/unchained.linux.amd64 main.go + GOOS=windows GOARCH=amd64 go build -o bin/unchained.windows.amd64.exe ./cmd/main.go + GOOS=darwin GOARCH=amd64 go build -o bin/unchained.darwin.amd64 ./cmd/main.go + GOOS=linux GOARCH=amd64 go build -o bin/unchained.linux.amd64 ./cmd/main.go - GOOS=windows GOARCH=arm64 go build -o bin/unchained.windows.arm64.exe main.go - GOOS=darwin GOARCH=arm64 go build -o bin/unchained.darwin.arm64 main.go - GOOS=linux GOARCH=arm64 go build -o bin/unchained.linux.arm64 main.go + GOOS=windows GOARCH=arm64 go build -o bin/unchained.windows.arm64.exe ./cmd/main.go + GOOS=darwin GOARCH=arm64 go build -o bin/unchained.darwin.arm64 ./cmd/main.go + GOOS=linux GOARCH=arm64 go build -o bin/unchained.linux.arm64 ./cmd/main.go find bin -type f -exec chmod u+x {} \; strip: - GOOS=windows GOARCH=amd64 go build -ldflags "-w -s" -o bin/unchained.windows.amd64.exe main.go - GOOS=darwin GOARCH=amd64 go build -ldflags "-w -s" -o bin/unchained.darwin.amd64 main.go - GOOS=linux GOARCH=amd64 go build -ldflags "-w -s" -o bin/unchained.linux.amd64 main.go + GOOS=windows GOARCH=amd64 go build -ldflags "-w -s" -o bin/unchained.windows.amd64.exe ./cmd/main.go + GOOS=darwin GOARCH=amd64 go build -ldflags "-w -s" -o bin/unchained.darwin.amd64 ./cmd/main.go + GOOS=linux GOARCH=amd64 go build -ldflags "-w -s" -o bin/unchained.linux.amd64 ./cmd/main.go - GOOS=windows GOARCH=arm64 go build -ldflags "-w -s" -o bin/unchained.windows.arm64.exe main.go - GOOS=darwin GOARCH=arm64 go build -ldflags "-w -s" -o bin/unchained.darwin.arm64 main.go - GOOS=linux GOARCH=arm64 go build -ldflags "-w -s" -o bin/unchained.linux.arm64 main.go + GOOS=windows GOARCH=arm64 go build -ldflags "-w -s" -o bin/unchained.windows.arm64.exe ./cmd/main.go + GOOS=darwin GOARCH=arm64 go build -ldflags "-w -s" -o bin/unchained.darwin.arm64 ./cmd/main.go + GOOS=linux GOARCH=arm64 go build -ldflags "-w -s" -o bin/unchained.linux.arm64 ./cmd/main.go find bin -type f -exec chmod u+x {} \; diff --git a/cmd/handler/broker.go b/cmd/handler/broker.go new file mode 100644 index 00000000..a5cbb256 --- /dev/null +++ b/cmd/handler/broker.go @@ -0,0 +1,38 @@ +package handler + +import ( + "github.com/KenshiTech/unchained/internal/app" + "github.com/KenshiTech/unchained/internal/config" + "github.com/KenshiTech/unchained/internal/log" + "github.com/spf13/cobra" +) + +// broker represents the broker command. +var broker = &cobra.Command{ + Use: "broker", + Short: "Run the Unchained client in broker mode", + Long: `Run the Unchained client in broker mode`, + Run: func(_ *cobra.Command, _ []string) { + err := config.Load(config.App.System.ConfigPath, config.App.System.SecretsPath) + if err != nil { + panic(err) + } + + log.Start(config.App.System.Log) + app.Broker() + }, +} + +// WithBrokerCmd appends the broker command to the root command. +func WithBrokerCmd(cmd *cobra.Command) { + cmd.AddCommand(broker) +} + +func init() { + broker.Flags().StringP( + "broker", + "b", + "wss://shinobi.brokers.kenshi.io", + "Unchained broker to connect to", + ) +} diff --git a/cmd/handler/consumer.go b/cmd/handler/consumer.go new file mode 100644 index 00000000..84f382f8 --- /dev/null +++ b/cmd/handler/consumer.go @@ -0,0 +1,51 @@ +package handler + +import ( + "github.com/KenshiTech/unchained/internal/app" + "github.com/KenshiTech/unchained/internal/config" + "github.com/KenshiTech/unchained/internal/log" + "github.com/spf13/cobra" +) + +// consumer represents the consumer command. +var consumer = &cobra.Command{ + Use: "consumer", + Short: "Run the Unchained client in consumer mode", + Long: `Run the Unchained client in consumer mode`, + + PreRun: func(cmd *cobra.Command, _ []string) { + config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() + config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() + }, + + Run: func(_ *cobra.Command, _ []string) { + err := config.Load(config.App.System.ConfigPath, config.App.System.SecretsPath) + if err != nil { + panic(err) + } + + log.Start(config.App.System.Log) + app.Consumer() + }, +} + +// WithConsumerCmd append command of consumer to the root command. +func WithConsumerCmd(cmd *cobra.Command) { + cmd.AddCommand(consumer) +} + +func init() { + consumer.Flags().StringP( + "broker", + "b", + "wss://shinobi.brokers.kenshi.io", + "Unchained broker to connect to", + ) + + consumer.Flags().StringP( + "graphql", + "g", + "127.0.0.1:8080", + "The graphql server path to bind", + ) +} diff --git a/cmd/handler/worker.go b/cmd/handler/worker.go new file mode 100644 index 00000000..71f4e844 --- /dev/null +++ b/cmd/handler/worker.go @@ -0,0 +1,43 @@ +package handler + +import ( + "github.com/KenshiTech/unchained/internal/app" + "github.com/KenshiTech/unchained/internal/config" + "github.com/KenshiTech/unchained/internal/log" + "github.com/spf13/cobra" +) + +// worker represents the worker command. +var worker = &cobra.Command{ + Use: "worker", + Short: "Run the Unchained client in worker mode", + Long: `Run the Unchained client in worker mode`, + + PreRun: func(cmd *cobra.Command, _ []string) { + config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() + }, + + Run: func(_ *cobra.Command, _ []string) { + err := config.Load(config.App.System.ConfigPath, config.App.System.SecretsPath) + if err != nil { + panic(err) + } + + log.Start(config.App.System.Log) + app.Worker() + }, +} + +// WithWorkerCmd appends the worker command to the root command. +func WithWorkerCmd(cmd *cobra.Command) { + cmd.AddCommand(worker) +} + +func init() { + worker.Flags().StringP( + "broker", + "b", + "wss://shinobi.brokers.kenshi.io", + "Unchained broker to connect to", + ) +} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 00000000..7d389d86 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "fmt" + "os" + + "github.com/KenshiTech/unchained/cmd/handler" + "github.com/KenshiTech/unchained/internal/config" + "github.com/KenshiTech/unchained/internal/constants" + "github.com/spf13/cobra" +) + +// root represents the root command of application. +var root = &cobra.Command{ + Use: "unchained", + Short: "Unchained is the universal data validation and processing protocol", + Long: `Unchained is the universal data validation and processing protocol`, + Run: func(_ *cobra.Command, _ []string) { + if config.App.System.PrintVersion { + fmt.Println(constants.Version) + } else { + os.Exit(1) + } + }, +} + +func main() { + handler.WithBrokerCmd(root) + handler.WithConsumerCmd(root) + handler.WithWorkerCmd(root) + + err := root.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + root.Flags().BoolVarP(&config.App.System.PrintVersion, "version", "v", false, "Print the Unchained version number and die") + root.PersistentFlags().StringVarP(&config.App.System.ConfigPath, "config", "c", "./conf.yaml", "Config file") + root.PersistentFlags().StringVarP(&config.App.System.SecretsPath, "secrets", "s", "./secrets.yaml", "Secrets file") + root.PersistentFlags().StringVarP(&config.App.System.ContextPath, "context", "x", "./context", "Context DB") + + err := root.MarkPersistentFlagRequired("config") + if err != nil { + panic(err) + } + + err = root.MarkPersistentFlagFilename("config", "yaml") + if err != nil { + panic(err) + } +} diff --git a/internal/app/broker.go b/internal/app/broker.go new file mode 100644 index 00000000..2d80a061 --- /dev/null +++ b/internal/app/broker.go @@ -0,0 +1,32 @@ +package app + +import ( + "github.com/KenshiTech/unchained/internal/constants" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/log" + "github.com/KenshiTech/unchained/internal/pos" + "github.com/KenshiTech/unchained/internal/transport/server" + "github.com/KenshiTech/unchained/internal/transport/server/websocket" +) + +// Broker starts the Unchained broker and contains its DI. +func Broker() { + log.Logger. + With("Mode", "Broker"). + With("Version", constants.Version). + With("Protocol", constants.ProtocolVersion). + Info("Running Unchained") + + crypto.InitMachineIdentity( + crypto.WithBlsIdentity(), + crypto.WithEvmSigner(), + ) + + ethRPC := ethereum.New() + pos.New(ethRPC) + + server.New( + websocket.WithWebsocket(), + ) +} diff --git a/internal/app/consumer.go b/internal/app/consumer.go new file mode 100644 index 00000000..3ebfecaa --- /dev/null +++ b/internal/app/consumer.go @@ -0,0 +1,49 @@ +package app + +import ( + "github.com/KenshiTech/unchained/internal/constants" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/db" + "github.com/KenshiTech/unchained/internal/log" + "github.com/KenshiTech/unchained/internal/pos" + correctnessService "github.com/KenshiTech/unchained/internal/service/correctness" + evmlogService "github.com/KenshiTech/unchained/internal/service/evmlog" + uniswapService "github.com/KenshiTech/unchained/internal/service/uniswap" + "github.com/KenshiTech/unchained/internal/transport/client" + "github.com/KenshiTech/unchained/internal/transport/client/conn" + "github.com/KenshiTech/unchained/internal/transport/client/handler" + "github.com/KenshiTech/unchained/internal/transport/server" + "github.com/KenshiTech/unchained/internal/transport/server/gql" +) + +// Consumer starts the Unchained consumer and contains its DI. +func Consumer() { + log.Logger. + With("Mode", "Consumer"). + With("Version", constants.Version). + With("Protocol", constants.ProtocolVersion). + Info("Running Unchained") + + crypto.InitMachineIdentity( + crypto.WithEvmSigner(), + crypto.WithBlsIdentity(), + ) + + ethRPC := ethereum.New() + pos := pos.New(ethRPC) + db.Start() + + correctnessService := correctnessService.New(ethRPC) + evmLogService := evmlogService.New(ethRPC, pos) + uniswapService := uniswapService.New(ethRPC, pos) + + conn.Start() + + handler := handler.NewConsumerHandler(correctnessService, uniswapService, evmLogService) + client.NewRPC(handler) + + server.New( + gql.WithGraphQL(), + ) +} diff --git a/internal/app/worker.go b/internal/app/worker.go new file mode 100644 index 00000000..3efde5e8 --- /dev/null +++ b/internal/app/worker.go @@ -0,0 +1,50 @@ +package app + +import ( + "github.com/KenshiTech/unchained/internal/config" + "github.com/KenshiTech/unchained/internal/constants" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/log" + "github.com/KenshiTech/unchained/internal/persistence" + "github.com/KenshiTech/unchained/internal/pos" + "github.com/KenshiTech/unchained/internal/scheduler" + evmlogService "github.com/KenshiTech/unchained/internal/service/evmlog" + uniswapService "github.com/KenshiTech/unchained/internal/service/uniswap" + "github.com/KenshiTech/unchained/internal/transport/client" + "github.com/KenshiTech/unchained/internal/transport/client/conn" + "github.com/KenshiTech/unchained/internal/transport/client/handler" +) + +// Worker starts the Unchained worker and contains its DI. +func Worker() { + log.Logger. + With("Mode", "Worker"). + With("Version", constants.Version). + With("Protocol", constants.ProtocolVersion). + Info("Running Unchained") + + crypto.InitMachineIdentity( + crypto.WithEvmSigner(), + crypto.WithBlsIdentity(), + ) + + ethRPC := ethereum.New() + pos := pos.New(ethRPC) + badger := persistence.New(config.App.System.ContextPath) + + evmLogService := evmlogService.New(ethRPC, pos) + uniswapService := uniswapService.New(ethRPC, pos) + + scheduler := scheduler.New( + scheduler.WithEthLogs(evmLogService, ethRPC, badger), + scheduler.WithUniswapEvents(uniswapService, ethRPC), + ) + + conn.Start() + + handler := handler.NewWorkerHandler() + client.NewRPC(handler) + + scheduler.Start() +} diff --git a/internal/cmd/broker.go b/internal/cmd/broker.go deleted file mode 100644 index b21d7319..00000000 --- a/internal/cmd/broker.go +++ /dev/null @@ -1,51 +0,0 @@ -package cmd - -import ( - "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/constants" - "github.com/KenshiTech/unchained/internal/crypto/bls" - "github.com/KenshiTech/unchained/internal/ethereum" - "github.com/KenshiTech/unchained/internal/log" - "github.com/KenshiTech/unchained/internal/pos" - "github.com/KenshiTech/unchained/internal/transport/server" - "github.com/KenshiTech/unchained/internal/transport/server/websocket" - - "github.com/spf13/cobra" -) - -var brokerCmd = &cobra.Command{ - Use: "broker", - Short: "Run the Unchained client in broker mode", - Long: `Run the Unchained client in broker mode`, - Run: func(cmd *cobra.Command, args []string) { - log.Start(config.App.System.Log) - log.Logger. - With("Mode", "Broker"). - With("Version", constants.Version). - With("Protocol", constants.ProtocolVersion). - Info("Running Unchained") - - err := config.Load(configPath, secretsPath) - if err != nil { - panic(err) - } - - err = ethereum.InitClientIdentity() - if err != nil { - panic(err) - } - - bls.InitClientIdentity() - - ethRPC := ethereum.New() - pos.New(ethRPC) - - server.New( - websocket.WithWebsocket(), - ) - }, -} - -func init() { - rootCmd.AddCommand(brokerCmd) -} diff --git a/internal/cmd/consumer.go b/internal/cmd/consumer.go deleted file mode 100644 index fe5b14a5..00000000 --- a/internal/cmd/consumer.go +++ /dev/null @@ -1,87 +0,0 @@ -package cmd - -import ( - "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/constants" - "github.com/KenshiTech/unchained/internal/crypto/bls" - "github.com/KenshiTech/unchained/internal/db" - "github.com/KenshiTech/unchained/internal/ethereum" - "github.com/KenshiTech/unchained/internal/log" - "github.com/KenshiTech/unchained/internal/pos" - correctnessService "github.com/KenshiTech/unchained/internal/service/correctness" - evmlogService "github.com/KenshiTech/unchained/internal/service/evmlog" - uniswapService "github.com/KenshiTech/unchained/internal/service/uniswap" - "github.com/KenshiTech/unchained/internal/transport/client" - "github.com/KenshiTech/unchained/internal/transport/client/conn" - "github.com/KenshiTech/unchained/internal/transport/client/handler" - "github.com/KenshiTech/unchained/internal/transport/server" - "github.com/KenshiTech/unchained/internal/transport/server/gql" - "github.com/spf13/cobra" -) - -var consumerCmd = &cobra.Command{ - Use: "consumer", - Short: "Run the Unchained client in consumer mode", - Long: `Run the Unchained client in consumer mode`, - - PreRun: func(cmd *cobra.Command, args []string) { - config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() - config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() - }, - - Run: func(cmd *cobra.Command, args []string) { - log.Start(config.App.System.Log) - log.Logger. - With("Mode", "Consumer"). - With("Version", constants.Version). - With("Protocol", constants.ProtocolVersion). - Info("Running Unchained") - - err := config.Load(configPath, secretsPath) - if err != nil { - panic(err) - } - - err = ethereum.InitClientIdentity() - if err != nil { - panic(err) - } - - bls.InitClientIdentity() - - ethRPC := ethereum.New() - pos := pos.New(ethRPC) - db.Start() - - correctnessService := correctnessService.New(ethRPC) - evmLogService := evmlogService.New(ethRPC, pos) - uniswapService := uniswapService.New(ethRPC, pos) - - conn.Start() - - handler := handler.NewConsumerHandler(correctnessService, uniswapService, evmLogService) - client.NewRPC(handler) - - server.New( - gql.WithGraphQL(), - ) - }, -} - -func init() { - rootCmd.AddCommand(consumerCmd) - - consumerCmd.Flags().StringP( - "broker", - "b", - "wss://shinobi.brokers.kenshi.io", - "Unchained broker to connect to", - ) - - consumerCmd.Flags().StringP( - "graphql", - "g", - "127.0.0.1:8080", - "The graphql server path to bind", - ) -} diff --git a/internal/cmd/root.go b/internal/cmd/root.go deleted file mode 100644 index d418019e..00000000 --- a/internal/cmd/root.go +++ /dev/null @@ -1,54 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - - "github.com/ethereum/go-ethereum/log" - - "github.com/KenshiTech/unchained/internal/constants" - "github.com/spf13/cobra" -) - -var configPath string -var secretsPath string -var contextPath string -var printVersion bool - -var rootCmd = &cobra.Command{ - Use: "unchained", - Short: "Unchained is the universal data validation and processing protocol", - Long: `Unchained is the universal data validation and processing protocol`, - - Run: func(cmd *cobra.Command, args []string) { - if printVersion { - fmt.Println(constants.Version) - } else { - os.Exit(1) - } - }, -} - -func Execute() { - err := rootCmd.Execute() - if err != nil { - os.Exit(1) - } -} - -func init() { - rootCmd.Flags().BoolVarP(&printVersion, "version", "v", false, "Print the Unchained version number and die") - - rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "./conf.yaml", "Config file") - rootCmd.PersistentFlags().StringVarP(&secretsPath, "secrets", "s", "./secrets.yaml", "Secrets file") - rootCmd.PersistentFlags().StringVarP(&contextPath, "context", "x", "./context", "Context DB") - err := rootCmd.MarkFlagFilename("config", "yaml") - if err != nil { - log.Warn("no config flag") - } - - err = rootCmd.MarkFlagRequired("config") - if err != nil { - log.Warn("no config flag") - } -} diff --git a/internal/cmd/worker.go b/internal/cmd/worker.go deleted file mode 100644 index 5e3ec119..00000000 --- a/internal/cmd/worker.go +++ /dev/null @@ -1,80 +0,0 @@ -package cmd - -import ( - "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/constants" - "github.com/KenshiTech/unchained/internal/crypto/bls" - "github.com/KenshiTech/unchained/internal/ethereum" - "github.com/KenshiTech/unchained/internal/log" - "github.com/KenshiTech/unchained/internal/persistence" - "github.com/KenshiTech/unchained/internal/pos" - "github.com/KenshiTech/unchained/internal/scheduler" - evmlogService "github.com/KenshiTech/unchained/internal/service/evmlog" - uniswapService "github.com/KenshiTech/unchained/internal/service/uniswap" - "github.com/KenshiTech/unchained/internal/transport/client" - "github.com/KenshiTech/unchained/internal/transport/client/conn" - "github.com/KenshiTech/unchained/internal/transport/client/handler" - "github.com/spf13/cobra" -) - -// workerCmd represents the worker command. -var workerCmd = &cobra.Command{ - Use: "worker", - Short: "Run the Unchained client in worker mode", - Long: `Run the Unchained client in worker mode`, - - PreRun: func(cmd *cobra.Command, args []string) { - config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() - }, - - Run: func(cmd *cobra.Command, args []string) { - log.Start(config.App.System.Log) - log.Logger. - With("Mode", "Worker"). - With("Version", constants.Version). - With("Protocol", constants.ProtocolVersion). - Info("Running Unchained ") - - err := config.Load(configPath, secretsPath) - if err != nil { - panic(err) - } - - err = ethereum.InitClientIdentity() - if err != nil { - panic(err) - } - - bls.InitClientIdentity() - - ethRPC := ethereum.New() - pos := pos.New(ethRPC) - badger := persistence.New(contextPath) - - evmLogService := evmlogService.New(ethRPC, pos) - uniswapService := uniswapService.New(ethRPC, pos) - - scheduler := scheduler.New( - scheduler.WithEthLogs(evmLogService, ethRPC, badger), - scheduler.WithUniswapEvents(uniswapService, ethRPC), - ) - - conn.Start() - - handler := handler.NewWorkerHandler() - client.NewRPC(handler) - - scheduler.Start() - }, -} - -func init() { - rootCmd.AddCommand(workerCmd) - - workerCmd.Flags().StringP( - "broker", - "b", - "wss://shinobi.brokers.kenshi.io", - "Unchained broker to connect to", - ) -} diff --git a/internal/config/config.go b/internal/config/config.go index 8fc3d996..4bf584cf 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,6 +3,8 @@ package config import ( "os" + pureLog "log" + "github.com/KenshiTech/unchained/internal/log" "github.com/KenshiTech/unchained/internal/constants" @@ -26,13 +28,12 @@ func Load(configPath, secretPath string) error { SecretFilePath = secretPath err := cleanenv.ReadConfig(secretPath, &App.Secret) if err != nil { - log.Logger.With("Error", err).Warn("Can't read secret file") + pureLog.Println("Can't load secrets") // return constants.ErrCantLoadSecret } err = cleanenv.ReadConfig(configPath, &App) if err != nil { - log.Logger.With("Error", err).Error("Can't read config file") return constants.ErrCantLoadConfig } diff --git a/internal/config/model.go b/internal/config/model.go index 078e815a..111d21a5 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -4,9 +4,15 @@ import ( "time" ) +// System struct hold the internal system configuration. type System struct { Name string `env:"SYSTEM_NAME" env-default:"Unchained" yaml:"name"` Log string `env:"SYSTEM_LOG" env-default:"info" yaml:"log"` + + ConfigPath string + SecretsPath string + ContextPath string + PrintVersion bool } type RPC struct { @@ -70,6 +76,7 @@ type Postgres struct { URL string `env:"DATABASE_URL" yaml:"url"` } +// Secret struct hold the secret keys of the application and loaded from secret.yaml. type Secret struct { Address string `env:"ADDRESS" yaml:"address"` EvmAddress string `env:"EVM_ADDRESS" yaml:"evmAddress"` @@ -78,6 +85,7 @@ type Secret struct { EvmPrivateKey string `env:"EVM_PRIVATE_KEY" yaml:"evmPrivateKey"` } +// Config struct is the main configuration struct of application. type Config struct { System System `yaml:"system"` Network Network `yaml:"network"` diff --git a/internal/crypto/bls/bls.go b/internal/crypto/bls/bls.go index e5b6b4d4..59223f5f 100644 --- a/internal/crypto/bls/bls.go +++ b/internal/crypto/bls/bls.go @@ -1,65 +1,11 @@ package bls import ( - "crypto/rand" "math/big" bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" - bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" ) -var ( - g2Aff bls12381.G2Affine - g1Aff bls12381.G1Affine -) - -func init() { - _, _, g1Aff, g2Aff = bls12381.Generators() -} - -func GetPublicKey(sk *big.Int) *bls12381.G2Affine { - return new(bls12381.G2Affine).ScalarMultiplication(&g2Aff, sk) -} - -func GetShortPublicKey(sk *big.Int) *bls12381.G1Affine { - return new(bls12381.G1Affine).ScalarMultiplication(&g1Aff, sk) -} - -// generate BLS private and public key pair. -func GenerateKeyPair() (*big.Int, *bls12381.G2Affine, error) { - // generate a random point in G2 - g2Order := bls12381_fr.Modulus() - sk, err := rand.Int(rand.Reader, g2Order) - - if err != nil { - return nil, nil, err - } - - pk := GetPublicKey(sk) - - return sk, pk, nil -} - -func Verify( - signature bls12381.G1Affine, - hashedMessage bls12381.G1Affine, - publicKey bls12381.G2Affine) (bool, error) { - pairingSigG2, err := bls12381.Pair( - []bls12381.G1Affine{signature}, - []bls12381.G2Affine{g2Aff}) - if err != nil { - return false, err - } - - pairingHmPk, pairingError := bls12381.Pair( - []bls12381.G1Affine{hashedMessage}, - []bls12381.G2Affine{publicKey}) - - ok := pairingSigG2.Equal(&pairingHmPk) - - return ok, pairingError -} - func FastVerify( signature bls12381.G1Affine, g2Gen bls12381.G2Affine, diff --git a/internal/crypto/bls/identity.go b/internal/crypto/bls/identity.go new file mode 100644 index 00000000..6cfe01bc --- /dev/null +++ b/internal/crypto/bls/identity.go @@ -0,0 +1,93 @@ +package bls + +import ( + "crypto/rand" + "encoding/hex" + "math/big" + + "github.com/KenshiTech/unchained/internal/config" + "github.com/btcsuite/btcutil/base58" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" + bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" +) + +type Signer struct { + Name string + EvmAddress string + SecretKey *big.Int + PublicKey *bls12381.G2Affine + ShortPublicKey *bls12381.G1Affine + + g2Aff bls12381.G2Affine + g1Aff bls12381.G1Affine +} + +func NewIdentity() *Signer { + b := &Signer{ + SecretKey: new(big.Int), + } + + _, _, b.g1Aff, b.g2Aff = bls12381.Generators() + + if config.App.Secret.SecretKey != "" { + decoded, err := hex.DecodeString(config.App.Secret.SecretKey) + + if err != nil { + // TODO: Backwards compatibility with base58 encoded secret keys + // Remove this after a few releases + decoded = base58.Decode(config.App.Secret.SecretKey) + } + + b.SecretKey.SetBytes(decoded) + b.PublicKey = b.getPublicKey(b.SecretKey) + } else { + b.generateKeyPair() + } + + b.ShortPublicKey = b.getShortPublicKey(b.SecretKey) + + return b +} + +func (b *Signer) getPublicKey(sk *big.Int) *bls12381.G2Affine { + return new(bls12381.G2Affine).ScalarMultiplication(&b.g2Aff, sk) +} + +func (b *Signer) getShortPublicKey(sk *big.Int) *bls12381.G1Affine { + return new(bls12381.G1Affine).ScalarMultiplication(&b.g1Aff, sk) +} + +func (b *Signer) generateKeyPair() { + // generate a random point in G2 + g2Order := bls12381_fr.Modulus() + sk, err := rand.Int(rand.Reader, g2Order) + + if err != nil { + panic(err) + } + + pk := b.getPublicKey(sk) + + b.SecretKey = sk + b.PublicKey = pk +} + +func (b *Signer) Verify( + signature bls12381.G1Affine, + hashedMessage bls12381.G1Affine, + publicKey bls12381.G2Affine) (bool, error) { + pairingSigG2, err := bls12381.Pair( + []bls12381.G1Affine{signature}, + []bls12381.G2Affine{b.g2Aff}) + if err != nil { + return false, err + } + + pairingHmPk, pairingError := bls12381.Pair( + []bls12381.G1Affine{hashedMessage}, + []bls12381.G2Affine{publicKey}) + + ok := pairingSigG2.Equal(&pairingHmPk) + + return ok, pairingError +} diff --git a/internal/crypto/bls/store.go b/internal/crypto/bls/store.go deleted file mode 100644 index 0c4e3251..00000000 --- a/internal/crypto/bls/store.go +++ /dev/null @@ -1,91 +0,0 @@ -package bls - -import ( - "encoding/hex" - "math/big" - - "github.com/KenshiTech/unchained/internal/address" - "github.com/KenshiTech/unchained/internal/datasets" - "github.com/KenshiTech/unchained/internal/ethereum" - "github.com/KenshiTech/unchained/internal/log" - - "github.com/KenshiTech/unchained/internal/config" - - "github.com/btcsuite/btcutil/base58" - - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" -) - -var ClientSecretKey *big.Int -var ClientPublicKey *bls12381.G2Affine -var ClientShortPublicKey *bls12381.G1Affine -var ClientSigner datasets.Signer - -func saveConfig() { - pkBytes := ClientPublicKey.Bytes() - - config.App.Secret.SecretKey = hex.EncodeToString(ClientSecretKey.Bytes()) - config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) - err := config.App.Secret.Save() - - if err != nil { - panic(err) - } -} - -func InitClientIdentity() { - var err error - - if config.App.Secret.SecretKey != "" { - decoded, err := hex.DecodeString(config.App.Secret.SecretKey) - - if err != nil { - // TODO: Backwards compatibility with base58 encoded secret keys - // Remove this after a few releases - decoded = base58.Decode(config.App.Secret.SecretKey) - } - - ClientSecretKey = new(big.Int) - ClientSecretKey.SetBytes(decoded) - ClientPublicKey = GetPublicKey(ClientSecretKey) - - if err != nil { - saveConfig() - } - } else { - ClientSecretKey, ClientPublicKey, err = GenerateKeyPair() - if err != nil { - panic(err) - } - - saveConfig() - } - - ClientShortPublicKey = GetShortPublicKey(ClientSecretKey) - - pkBytes := ClientPublicKey.Bytes() - addrStr := address.Calculate(pkBytes[:]) - - ClientSigner = datasets.Signer{ - Name: config.App.System.Name, - EvmAddress: ethereum.EvmSignerInstance.Address, - PublicKey: ClientPublicKey.Bytes(), - ShortPublicKey: ClientShortPublicKey.Bytes(), - } - - log.Logger. - With("Address", addrStr). - Info("Unchained identity initialized") - - // TODO: Avoid recalculating this - config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) - - if config.App.Secret.Address != "" { - config.App.Secret.Address = addrStr - err := config.App.Secret.Save() - - if err != nil { - panic(err) - } - } -} diff --git a/internal/ethereum/contracts/UnchainedStaking.go b/internal/crypto/ethereum/contracts/UnchainedStaking.go similarity index 100% rename from internal/ethereum/contracts/UnchainedStaking.go rename to internal/crypto/ethereum/contracts/UnchainedStaking.go diff --git a/internal/ethereum/contracts/UniV3.go b/internal/crypto/ethereum/contracts/UniV3.go similarity index 100% rename from internal/ethereum/contracts/UniV3.go rename to internal/crypto/ethereum/contracts/UniV3.go diff --git a/internal/ethereum/rpc.go b/internal/crypto/ethereum/rpc.go similarity index 96% rename from internal/ethereum/rpc.go rename to internal/crypto/ethereum/rpc.go index b6a12157..65eefba9 100644 --- a/internal/ethereum/rpc.go +++ b/internal/crypto/ethereum/rpc.go @@ -5,9 +5,10 @@ import ( "fmt" "sync" + "github.com/KenshiTech/unchained/internal/crypto/ethereum/contracts" + "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/ethereum/contracts" "github.com/KenshiTech/unchained/internal/log" "github.com/ethereum/go-ethereum/common" diff --git a/internal/crypto/ethereum/signer.go b/internal/crypto/ethereum/signer.go new file mode 100644 index 00000000..92b02168 --- /dev/null +++ b/internal/crypto/ethereum/signer.go @@ -0,0 +1,11 @@ +package ethereum + +import ( + "crypto/ecdsa" +) + +type EvmSigner struct { + PublicKey *ecdsa.PublicKey + PrivateKey *ecdsa.PrivateKey + Address string +} diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go new file mode 100644 index 00000000..174bb736 --- /dev/null +++ b/internal/crypto/identity.go @@ -0,0 +1,137 @@ +package crypto + +import ( + "crypto/ecdsa" + "encoding/hex" + + "github.com/KenshiTech/unchained/internal/address" + "github.com/KenshiTech/unchained/internal/config" + "github.com/KenshiTech/unchained/internal/crypto/bls" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/datasets" + "github.com/KenshiTech/unchained/internal/log" + "github.com/ethereum/go-ethereum/common/hexutil" + ethCrypto "github.com/ethereum/go-ethereum/crypto" +) + +// MachineIdentity holds machine identity and provide and manage keys. +type MachineIdentity struct { + Bls *bls.Signer + Eth *ethereum.EvmSigner +} + +var Identity = &MachineIdentity{} + +type Option func(identity *MachineIdentity) error + +// InitMachineIdentity loads all provided identities and save them to secret file. +func InitMachineIdentity(options ...Option) { + for _, option := range options { + err := option(Identity) + if err != nil { + panic(err) + } + } + + err := config.App.Secret.Save() + if err != nil { + panic(err) + } +} + +func (i *MachineIdentity) ExportBlsSigner() *datasets.Signer { + return &datasets.Signer{ + Name: config.App.System.Name, + EvmAddress: Identity.Eth.Address, + PublicKey: Identity.Bls.PublicKey.Bytes(), + ShortPublicKey: Identity.Bls.ShortPublicKey.Bytes(), + } +} + +// WithEvmSigner initialize and will add Evm keys to machine identity. +func WithEvmSigner() func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + var privateKey *ecdsa.PrivateKey + var err error + var privateKeyRegenerated bool + + if config.App.Secret.EvmPrivateKey != "" { + privateKey, err = ethCrypto.HexToECDSA(config.App.Secret.EvmPrivateKey) + + if err != nil { + log.Logger. + With("Error", err). + Error("Can't decode EVM private key") + + return err + } + + privateKeyRegenerated = true + } else { + privateKey, err = ethCrypto.GenerateKey() + + if err != nil { + log.Logger. + With("Error", err). + Error("Can't generate EVM private key") + + return err + } + } + + publicKey := privateKey.Public() + publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) + + if !ok { + log.Logger.Error("Can't assert type: publicKey is not of type *ecdsa.PublicKey") + return err + } + + ethAddress := ethCrypto.PubkeyToAddress(*publicKeyECDSA).Hex() + + machineIdentity.Eth = ðereum.EvmSigner{ + PublicKey: publicKeyECDSA, + PrivateKey: privateKey, + Address: ethAddress, + } + + if privateKeyRegenerated || config.App.Secret.EvmAddress == "" { + privateKeyBytes := ethCrypto.FromECDSA(machineIdentity.Eth.PrivateKey) + + config.App.Secret.EvmPrivateKey = hexutil.Encode(privateKeyBytes)[2:] + config.App.Secret.EvmAddress = machineIdentity.Eth.Address + } + + log.Logger. + With("Address", machineIdentity.Eth.Address). + Info("EVM identity initialized") + + return nil + } +} + +// WithBlsIdentity initialize and will add Bls keys to machine identity. +func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + machineIdentity.Bls = bls.NewIdentity() + pkBytes := machineIdentity.Bls.PublicKey.Bytes() + + config.App.Secret.SecretKey = hex.EncodeToString(machineIdentity.Bls.SecretKey.Bytes()) + config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) + + addrStr := address.Calculate(pkBytes[:]) + + log.Logger. + With("Address", addrStr). + Info("Unchained identity initialized") + + // TODO: Avoid recalculating this + config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) + + if config.App.Secret.Address != "" { + config.App.Secret.Address = addrStr + } + + return nil + } +} diff --git a/internal/crypto/kosk/kosk.go b/internal/crypto/kosk/kosk.go index 511b60c5..8223dc0e 100644 --- a/internal/crypto/kosk/kosk.go +++ b/internal/crypto/kosk/kosk.go @@ -1,10 +1,10 @@ package kosk -// TODO: Move to "crypto" - import ( "crypto/rand" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/bls" sia "github.com/pouya-eghbali/go-sia/v2/pkg" @@ -48,7 +48,6 @@ func NewChallenge() [LenOfChallenge]byte { } // TODO: We should use small signatures - func VerifyChallenge(challenge [LenOfChallenge]byte, publicKeyBytes [LenOfPublicKey]byte, signatureBytes [LenOfSignature]byte) (bool, error) { @@ -67,5 +66,5 @@ func VerifyChallenge(challenge [LenOfChallenge]byte, return false, err } - return bls.Verify(signature, hash, publicKey) + return crypto.Identity.Bls.Verify(signature, hash, publicKey) } diff --git a/internal/db/db.go b/internal/db/db.go index 7fed2216..cb92273d 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -11,6 +11,8 @@ import ( "entgo.io/ent/dialect" entsql "entgo.io/ent/dialect/sql" + + // these imports are required for ent to work with postgres. _ "github.com/jackc/pgx/v5/stdlib" _ "github.com/lib/pq" ) diff --git a/internal/ethereum/signer.go b/internal/ethereum/signer.go deleted file mode 100644 index 32f637b6..00000000 --- a/internal/ethereum/signer.go +++ /dev/null @@ -1,95 +0,0 @@ -package ethereum - -import ( - "crypto/ecdsa" - - "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/log" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" -) - -type EvmSigner struct { - PublicKey *ecdsa.PublicKey - PrivateKey *ecdsa.PrivateKey - Address string -} - -var EvmSignerInstance *EvmSigner - -func saveConfig() error { - privateKeyBytes := crypto.FromECDSA(EvmSignerInstance.PrivateKey) - - config.App.Secret.EvmPrivateKey = hexutil.Encode(privateKeyBytes)[2:] - config.App.Secret.EvmAddress = EvmSignerInstance.Address - err := config.App.Secret.Save() - - if err != nil { - log.Logger. - With("Error", err). - Error("Can't save EVM identity to the config") - } - - return err -} - -func InitClientIdentity() error { - var privateKey *ecdsa.PrivateKey - var err error - var privateKeyRegenerated bool - - if config.App.Secret.EvmPrivateKey != "" { - privateKey, err = crypto.HexToECDSA(config.App.Secret.EvmPrivateKey) - - if err != nil { - log.Logger. - With("Error", err). - Error("Can't decode EVM private key") - - return err - } - - privateKeyRegenerated = true - } else { - privateKey, err = crypto.GenerateKey() - - if err != nil { - log.Logger. - With("Error", err). - Error("Can't generate EVM private key") - - return err - } - } - - publicKey := privateKey.Public() - publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) - - if !ok { - log.Logger.Error("Can't assert type: publicKey is not of type *ecdsa.PublicKey") - return err - } - - address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex() - - EvmSignerInstance = &EvmSigner{ - PublicKey: publicKeyECDSA, - PrivateKey: privateKey, - Address: address, - } - - if privateKeyRegenerated || config.App.Secret.EvmAddress == "" { - err := saveConfig() - - if err != nil { - return err - } - } - - log.Logger. - With("Address", EvmSignerInstance.Address). - Info("EVM identity initialized") - - return nil -} diff --git a/internal/log/logger.go b/internal/log/logger.go index 2227cdff..5b7a9410 100644 --- a/internal/log/logger.go +++ b/internal/log/logger.go @@ -9,19 +9,18 @@ import ( ) var Logger *slog.Logger -var Levels map[string]slog.Level - -func init() { - Levels = make(map[string]slog.Level) - Levels["info"] = slog.LevelInfo - Levels["warn"] = slog.LevelWarn - Levels["debug"] = slog.LevelDebug - Levels["error"] = slog.LevelError -} func Start(logLevel string) { + levels := make(map[string]slog.Level) + levels["info"] = slog.LevelInfo + levels["warn"] = slog.LevelWarn + levels["debug"] = slog.LevelDebug + levels["error"] = slog.LevelError + Logger = slog.New(tint.NewHandler(colorable.NewColorableStdout(), &tint.Options{ - Level: Levels[logLevel], + Level: levels[logLevel], TimeFormat: time.RFC3339, })) + + Logger.With("Level", logLevel).Info("Logger started") } diff --git a/internal/pos/eip712.go b/internal/pos/eip712.go index ea95b2a1..1f46d731 100644 --- a/internal/pos/eip712.go +++ b/internal/pos/eip712.go @@ -4,8 +4,10 @@ import ( "context" "math/big" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/ethereum/contracts" + "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/ethereum/contracts" "github.com/KenshiTech/unchained/internal/log" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -13,7 +15,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -func (s *Repository) Slash(address [20]byte, to common.Address, amount *big.Int, nftIds []*big.Int) error { +func (s *Repository) Slash(address [20]byte, to common.Address, amount *big.Int, nftIDs []*big.Int) error { evmAddress, err := s.posContract.EvmAddressOf(nil, address) if err != nil { @@ -27,10 +29,10 @@ func (s *Repository) Slash(address [20]byte, to common.Address, amount *big.Int, From: evmAddress, To: to, Amount: amount, - NftIds: nftIds, + NftIds: nftIDs, } - signature, err := s.eip712Signer.SignTransferRequest(s.evmSigner, &transfer) + signature, err := s.eip712Signer.SignTransferRequest(crypto.Identity.Eth, &transfer) if err != nil { log.Logger. @@ -76,7 +78,7 @@ func (s *Repository) Slash(address [20]byte, to common.Address, amount *big.Int, With("Address", evmAddress.Hex()). With("To", to.Hex()). With("Amount", amount.String()). - With("NftIds", nftIds). + With("NftIds", nftIDs). Info("Slashed") return nil diff --git a/internal/pos/eip712/sign.go b/internal/pos/eip712/sign.go index 6a8f5d07..5ce2859b 100644 --- a/internal/pos/eip712/sign.go +++ b/internal/pos/eip712/sign.go @@ -4,18 +4,19 @@ import ( "fmt" "math/big" - "github.com/KenshiTech/unchained/internal/ethereum" - "github.com/KenshiTech/unchained/internal/ethereum/contracts" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/crypto/ethereum/contracts" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/signer/core/apitypes" ) -type EIP712Signer struct { +type Signer struct { domain apitypes.TypedDataDomain } -func (s *EIP712Signer) bytesToUnchainedSignature(signature []byte) *contracts.UnchainedStakingSignature { +func (s *Signer) bytesToUnchainedSignature(signature []byte) *contracts.UnchainedStakingSignature { return &contracts.UnchainedStakingSignature{ V: signature[64], R: [32]byte(signature[:32]), @@ -23,7 +24,7 @@ func (s *EIP712Signer) bytesToUnchainedSignature(signature []byte) *contracts.Un } } -func (s *EIP712Signer) signEip712Message(evmSigner *ethereum.EvmSigner, data *apitypes.TypedData) (*contracts.UnchainedStakingSignature, error) { +func (s *Signer) signEip712Message(evmSigner *ethereum.EvmSigner, data *apitypes.TypedData) (*contracts.UnchainedStakingSignature, error) { domainSeparator, err := data.HashStruct("EIP712Domain", data.Domain.Map()) if err != nil { return nil, err @@ -49,7 +50,7 @@ func (s *EIP712Signer) signEip712Message(evmSigner *ethereum.EvmSigner, data *ap return s.bytesToUnchainedSignature(signature), nil } -func (s *EIP712Signer) SignTransferRequest(evmSigner *ethereum.EvmSigner, request *contracts.UnchainedStakingEIP712Transfer) (*contracts.UnchainedStakingSignature, error) { +func (s *Signer) SignTransferRequest(evmSigner *ethereum.EvmSigner, request *contracts.UnchainedStakingEIP712Transfer) (*contracts.UnchainedStakingSignature, error) { data := &apitypes.TypedData{ Types: Types, PrimaryType: "Transfer", @@ -67,7 +68,7 @@ func (s *EIP712Signer) SignTransferRequest(evmSigner *ethereum.EvmSigner, reques return s.signEip712Message(evmSigner, data) } -func (s *EIP712Signer) SignSetParamsRequest(evmSigner *ethereum.EvmSigner, request *contracts.UnchainedStakingEIP712SetParams) (*contracts.UnchainedStakingSignature, error) { +func (s *Signer) SignSetParamsRequest(evmSigner *ethereum.EvmSigner, request *contracts.UnchainedStakingEIP712SetParams) (*contracts.UnchainedStakingSignature, error) { data := &apitypes.TypedData{ Types: Types, PrimaryType: "SetParams", @@ -86,7 +87,7 @@ func (s *EIP712Signer) SignSetParamsRequest(evmSigner *ethereum.EvmSigner, reque return s.signEip712Message(evmSigner, data) } -func (s *EIP712Signer) SignSetNftPriceRequest(evmSigner *ethereum.EvmSigner, request *contracts.UnchainedStakingEIP712SetNftPrice) (*contracts.UnchainedStakingSignature, error) { +func (s *Signer) SignSetNftPriceRequest(evmSigner *ethereum.EvmSigner, request *contracts.UnchainedStakingEIP712SetNftPrice) (*contracts.UnchainedStakingSignature, error) { data := &apitypes.TypedData{ Types: Types, PrimaryType: "SetNftPrice", @@ -102,8 +103,8 @@ func (s *EIP712Signer) SignSetNftPriceRequest(evmSigner *ethereum.EvmSigner, req return s.signEip712Message(evmSigner, data) } -func New(chainID *big.Int, verifyingContract string) *EIP712Signer { - return &EIP712Signer{ +func New(chainID *big.Int, verifyingContract string) *Signer { + return &Signer{ domain: apitypes.TypedDataDomain{ Name: "Unchained", Version: "1.0.0", diff --git a/internal/pos/pos.go b/internal/pos/pos.go index 17a65cbd..eddfa593 100644 --- a/internal/pos/pos.go +++ b/internal/pos/pos.go @@ -4,11 +4,12 @@ import ( "math/big" "os" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/crypto/ethereum/contracts" + "github.com/KenshiTech/unchained/internal/address" "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/crypto/bls" - "github.com/KenshiTech/unchained/internal/ethereum" - "github.com/KenshiTech/unchained/internal/ethereum/contracts" "github.com/KenshiTech/unchained/internal/log" "github.com/KenshiTech/unchained/internal/pos/eip712" @@ -21,8 +22,7 @@ type Repository struct { votingPowers *xsync.MapOf[[20]byte, *big.Int] lastUpdated *xsync.MapOf[[20]byte, *big.Int] base *big.Int - evmSigner *ethereum.EvmSigner - eip712Signer *eip712.EIP712Signer + eip712Signer *eip712.Signer } func (s *Repository) GetTotalVotingPower() (*big.Int, error) { @@ -81,19 +81,16 @@ func (s *Repository) VotingPowerToFloat(power *big.Int) *big.Float { return powerFloat } -func New( - ethRPC *ethereum.Repository, -) *Repository { +func New(ethRPC *ethereum.Repository) *Repository { s := &Repository{ - ethRPC: ethRPC, - evmSigner: ethereum.EvmSignerInstance, + ethRPC: ethRPC, } s.init() s.base = big.NewInt(config.App.ProofOfStake.Base) - pkBytes := bls.ClientPublicKey.Bytes() + pkBytes := crypto.Identity.Bls.PublicKey.Bytes() addrHexStr, addrHex := address.CalculateHex(pkBytes[:]) log.Logger. diff --git a/internal/scheduler/logs/logs.go b/internal/scheduler/logs/logs.go index ce5cc073..d80a4524 100644 --- a/internal/scheduler/logs/logs.go +++ b/internal/scheduler/logs/logs.go @@ -9,10 +9,12 @@ import ( "sort" "strings" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/config" "github.com/KenshiTech/unchained/internal/crypto/bls" "github.com/KenshiTech/unchained/internal/datasets" - "github.com/KenshiTech/unchained/internal/ethereum" "github.com/KenshiTech/unchained/internal/log" "github.com/KenshiTech/unchained/internal/persistence" "github.com/KenshiTech/unchained/internal/service/evmlog" @@ -178,7 +180,7 @@ func (e *EvmLog) Run() { } toHash := event.Sia().Content - signature, hash := bls.Sign(*bls.ClientSecretKey, toHash) + signature, hash := bls.Sign(*crypto.Identity.Bls.SecretKey, toHash) if conf.Send { e.evmLogService.SendPriceReport(signature, event) @@ -187,7 +189,7 @@ func (e *EvmLog) Run() { if conf.Store { e.evmLogService.RecordSignature( signature, - bls.ClientSigner, + *crypto.Identity.ExportBlsSigner(), hash, event, false, diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index 86daf023..ef3051a5 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -4,7 +4,7 @@ import ( "os" "time" - "github.com/KenshiTech/unchained/internal/ethereum" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" "github.com/KenshiTech/unchained/internal/persistence" "github.com/KenshiTech/unchained/internal/scheduler/uniswap" @@ -17,14 +17,17 @@ import ( "github.com/go-co-op/gocron/v2" ) +// Scheduler represents the scheduler service in the application and handles running tasks in a specific duration.. type Scheduler struct { scheduler gocron.Scheduler } +// Task represents a task that can be scheduled by the scheduler. type Task interface { Run() } +// New creates a new scheduler service. func New(options ...func(s *Scheduler)) *Scheduler { s := &Scheduler{} diff --git a/internal/scheduler/uniswap/uniswap.go b/internal/scheduler/uniswap/uniswap.go index de693ebe..4ab66559 100644 --- a/internal/scheduler/uniswap/uniswap.go +++ b/internal/scheduler/uniswap/uniswap.go @@ -6,10 +6,11 @@ import ( "os" "strings" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/datasets" "github.com/KenshiTech/unchained/internal/config" - "github.com/KenshiTech/unchained/internal/ethereum" "github.com/KenshiTech/unchained/internal/log" "github.com/KenshiTech/unchained/internal/service/uniswap" lru "github.com/hashicorp/golang-lru/v2" diff --git a/internal/service/correctness/correctness.go b/internal/service/correctness/correctness.go index 6cc906ee..f1140901 100644 --- a/internal/service/correctness/correctness.go +++ b/internal/service/correctness/correctness.go @@ -5,6 +5,8 @@ import ( "sync" "time" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/config" "github.com/KenshiTech/unchained/internal/crypto/bls" "github.com/KenshiTech/unchained/internal/crypto/shake" @@ -13,7 +15,6 @@ import ( "github.com/KenshiTech/unchained/internal/ent" "github.com/KenshiTech/unchained/internal/ent/correctnessreport" "github.com/KenshiTech/unchained/internal/ent/signer" - "github.com/KenshiTech/unchained/internal/ethereum" "github.com/KenshiTech/unchained/internal/utils" bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" lru "github.com/hashicorp/golang-lru/v2" @@ -165,7 +166,7 @@ func (s *Service) SaveSignatures(args SaveSignatureArgs) { panic(err) } - signerIds, err := dbClient.Signer. + signerIDs, err := dbClient.Signer. Query(). Where(signer.KeyIn(keys...)). IDs(ctx) @@ -202,7 +203,7 @@ func (s *Service) SaveSignatures(args SaveSignatureArgs) { SetHash(args.Info.Hash[:]). SetTimestamp(args.Info.Timestamp). SetTopic(args.Info.Topic[:]). - AddSignerIDs(signerIds...). + AddSignerIDs(signerIDs...). OnConflictColumns("topic", "hash"). UpdateNewValues(). Exec(ctx) diff --git a/internal/service/evmlog/evmlog.go b/internal/service/evmlog/evmlog.go index 8990b45c..667db762 100644 --- a/internal/service/evmlog/evmlog.go +++ b/internal/service/evmlog/evmlog.go @@ -6,6 +6,8 @@ import ( "sync" "time" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/address" "github.com/KenshiTech/unchained/internal/config" "github.com/KenshiTech/unchained/internal/constants/opcodes" @@ -14,7 +16,6 @@ import ( "github.com/KenshiTech/unchained/internal/db" "github.com/KenshiTech/unchained/internal/ent" "github.com/KenshiTech/unchained/internal/ent/signer" - "github.com/KenshiTech/unchained/internal/ethereum" "github.com/KenshiTech/unchained/internal/log" "github.com/KenshiTech/unchained/internal/pos" "github.com/KenshiTech/unchained/internal/transport/client/conn" @@ -201,7 +202,7 @@ func (e *Service) SaveSignatures(args SaveSignatureArgs) { panic(err) } - signerIds, err := dbClient.Signer. + signerIDs, err := dbClient.Signer. Query(). Where(signer.KeyIn(keys...)). IDs(ctx) @@ -236,7 +237,7 @@ func (e *Service) SaveSignatures(args SaveSignatureArgs) { SetSignersCount(uint64(len(signatures))). SetSignature(signatureBytes[:]). SetArgs(args.Info.Args). - AddSignerIDs(signerIds...). + AddSignerIDs(signerIDs...). OnConflictColumns("block", "transaction", "index"). UpdateNewValues(). Exec(ctx) diff --git a/internal/service/uniswap/uniswap.go b/internal/service/uniswap/uniswap.go index d99bed67..488817db 100644 --- a/internal/service/uniswap/uniswap.go +++ b/internal/service/uniswap/uniswap.go @@ -9,6 +9,9 @@ import ( "sync" "time" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/crypto/ethereum" + "github.com/KenshiTech/unchained/internal/utils" "github.com/KenshiTech/unchained/internal/config" @@ -22,7 +25,6 @@ import ( "github.com/KenshiTech/unchained/internal/ent" "github.com/KenshiTech/unchained/internal/ent/helpers" "github.com/KenshiTech/unchained/internal/ent/signer" - "github.com/KenshiTech/unchained/internal/ethereum" "github.com/KenshiTech/unchained/internal/log" "github.com/KenshiTech/unchained/internal/pos" "github.com/KenshiTech/unchained/internal/service/evmlog" @@ -37,7 +39,7 @@ import ( ) const ( - OldBlockNumber = 96 + MaxBlockNumberDelta = 96 ) var DebouncedSaveSignatures func(key datasets.AssetKey, arg SaveSignatureArgs) @@ -121,7 +123,7 @@ func (u *Service) RecordSignature( if !historical { // TODO: this won't work for Arbitrum - if *blockNumber-info.Asset.Block > OldBlockNumber { + if *blockNumber-info.Asset.Block > MaxBlockNumberDelta { log.Logger. With("Packet", info.Asset.Block). With("Current", *blockNumber). @@ -177,47 +179,34 @@ func (u *Service) RecordSignature( return } - if isMajority { - reportLog := log.Logger. - With("Block", info.Asset.Block). - With("Price", info.Price.String()). - With("Token", info.Asset.Token.Name) - - reportedValues.Range(func(hash bls12381.G1Affine, value big.Int) bool { - reportLog = reportLog.With( - fmt.Sprintf("%x", hash.Bytes())[:8], - value.String(), - ) - return true - }) - reportedValues.Range(func(hash bls12381.G1Affine, value big.Int) bool { - reportLog = reportLog.With( - fmt.Sprintf("%x", hash.Bytes())[:8], - value.String(), - ) - return true - }) + reportLog := log.Logger. + With("Block", info.Asset.Block). + With("Price", info.Price.String()). + With("Token", info.Asset.Token.Name) - reportLog. - With("Majority", fmt.Sprintf("%x", hash.Bytes())[:8]). - Debug("Values") - - DebouncedSaveSignatures( - info.Asset, - SaveSignatureArgs{Hash: hash, Info: info}, + reportedValues.Range(func(hash bls12381.G1Affine, value big.Int) bool { + reportLog = reportLog.With( + fmt.Sprintf("%x", hash.Bytes())[:8], + value.String(), + ) + return true + }) + reportedValues.Range(func(hash bls12381.G1Affine, value big.Int) bool { + reportLog = reportLog.With( + fmt.Sprintf("%x", hash.Bytes())[:8], + value.String(), ) + return true + }) - if debounce { - DebouncedSaveSignatures( - info.Asset, - SaveSignatureArgs{Hash: hash, Info: info}, - ) - } else { - u.saveSignatures(SaveSignatureArgs{Hash: hash, Info: info}) - } - } else { - log.Logger.Debug("Not a majority") - } + reportLog. + With("Majority", fmt.Sprintf("%x", hash.Bytes())[:8]). + Debug("Values") + + DebouncedSaveSignatures( + info.Asset, + SaveSignatureArgs{Hash: hash, Info: info}, + ) } type SaveSignatureArgs struct { @@ -281,7 +270,7 @@ func (u *Service) saveSignatures(args SaveSignatureArgs) { panic(err) } - signerIds, err := dbClient.Signer. + signerIDs, err := dbClient.Signer. Query(). Where(signer.KeyIn(keys...)). IDs(ctx) @@ -313,7 +302,7 @@ func (u *Service) saveSignatures(args SaveSignatureArgs) { signatureBytes := aggregate.Bytes() - // TODO: Handle cases where signerIds need to be removed + // TODO: Handle cases where signerIDs need to be removed err = dbClient.AssetPrice. Create(). SetPair(strings.ToLower(args.Info.Asset.Token.Pair)). @@ -323,7 +312,7 @@ func (u *Service) saveSignatures(args SaveSignatureArgs) { SetPrice(&helpers.BigInt{Int: args.Info.Price}). SetSignersCount(uint64(len(signatures))). SetSignature(signatureBytes[:]). - AddSignerIDs(signerIds...). + AddSignerIDs(signerIDs...). OnConflictColumns("block", "chain", "asset", "pair"). UpdateNewValues(). Exec(ctx) @@ -498,7 +487,7 @@ func (u *Service) syncBlock(token datasets.Token, caser cases.Caser, key *datase } toHash := priceInfo.Sia().Content - signature, hash := bls.Sign(*bls.ClientSecretKey, toHash) + signature, hash := bls.Sign(*crypto.Identity.Bls.SecretKey, toHash) if token.Send && !conn.IsClosed { compressedSignature := signature.Bytes() @@ -515,7 +504,7 @@ func (u *Service) syncBlock(token datasets.Token, caser cases.Caser, key *datase if token.Store { u.RecordSignature( signature, - bls.ClientSigner, + *crypto.Identity.ExportBlsSigner(), hash, priceInfo, false, diff --git a/internal/transport/client/conn/conn.go b/internal/transport/client/conn/conn.go index f2023ea5..3b76f921 100644 --- a/internal/transport/client/conn/conn.go +++ b/internal/transport/client/conn/conn.go @@ -5,10 +5,11 @@ import ( "sync" "time" + "github.com/KenshiTech/unchained/internal/crypto" + "github.com/KenshiTech/unchained/internal/config" "github.com/KenshiTech/unchained/internal/constants" "github.com/KenshiTech/unchained/internal/constants/opcodes" - "github.com/KenshiTech/unchained/internal/crypto/bls" "github.com/KenshiTech/unchained/internal/log" "github.com/gorilla/websocket" @@ -36,12 +37,12 @@ func Start() { panic(err) } - Send(opcodes.Hello, bls.ClientSigner.Sia().Content) + Send(opcodes.Hello, crypto.Identity.ExportBlsSigner().Sia().Content) } func Reconnect(err error) { IsClosed = true - hello := bls.ClientSigner.Sia().Content + hello := crypto.Identity.ExportBlsSigner().Sia().Content if websocket.IsUnexpectedCloseError(err) { for i := 1; i < 6; i++ { diff --git a/internal/transport/client/handler/challenge.go b/internal/transport/client/handler/challenge.go index 5a06254b..5956f128 100644 --- a/internal/transport/client/handler/challenge.go +++ b/internal/transport/client/handler/challenge.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/KenshiTech/unchained/internal/crypto" "github.com/KenshiTech/unchained/internal/crypto/bls" "github.com/KenshiTech/unchained/internal/crypto/kosk" sia "github.com/pouya-eghbali/go-sia/v2/pkg" @@ -9,7 +10,7 @@ import ( func (h *consumer) Challenge(message []byte) *kosk.Challenge { challenge := new(kosk.Challenge).DeSia(&sia.Sia{Content: message}) - signature, _ := bls.Sign(*bls.ClientSecretKey, challenge.Random[:]) + signature, _ := bls.Sign(*crypto.Identity.Bls.SecretKey, challenge.Random[:]) challenge.Signature = signature.Bytes() return challenge @@ -18,7 +19,7 @@ func (h *consumer) Challenge(message []byte) *kosk.Challenge { func (w worker) Challenge(message []byte) *kosk.Challenge { challenge := new(kosk.Challenge).DeSia(&sia.Sia{Content: message}) - signature, _ := bls.Sign(*bls.ClientSecretKey, challenge.Random[:]) + signature, _ := bls.Sign(*crypto.Identity.Bls.SecretKey, challenge.Random[:]) challenge.Signature = signature.Bytes() return challenge diff --git a/internal/transport/client/handler/correctness.go b/internal/transport/client/handler/correctness.go index b44f0b53..5b319328 100644 --- a/internal/transport/client/handler/correctness.go +++ b/internal/transport/client/handler/correctness.go @@ -39,4 +39,4 @@ func (h *consumer) CorrectnessReport(message []byte) { ) } -func (w worker) CorrectnessReport(message []byte) {} +func (w worker) CorrectnessReport(_ []byte) {} diff --git a/internal/transport/client/handler/event.go b/internal/transport/client/handler/event.go index 656b6184..e87d4b1c 100644 --- a/internal/transport/client/handler/event.go +++ b/internal/transport/client/handler/event.go @@ -40,4 +40,4 @@ func (h *consumer) EventLog(message []byte) { ) } -func (w worker) EventLog(message []byte) {} +func (w worker) EventLog(_ []byte) {} diff --git a/internal/transport/client/handler/price.go b/internal/transport/client/handler/price.go index 9dd34bb8..e007a6e7 100644 --- a/internal/transport/client/handler/price.go +++ b/internal/transport/client/handler/price.go @@ -40,4 +40,4 @@ func (h *consumer) PriceReport(message []byte) { ) } -func (w worker) PriceReport(message []byte) {} +func (w worker) PriceReport(_ []byte) {} diff --git a/internal/transport/server/websocket/handler/correctness.go b/internal/transport/server/websocket/handler/correctness.go index c22ee999..a2d56775 100644 --- a/internal/transport/server/websocket/handler/correctness.go +++ b/internal/transport/server/websocket/handler/correctness.go @@ -2,6 +2,7 @@ package handler import ( "github.com/KenshiTech/unchained/internal/constants" + "github.com/KenshiTech/unchained/internal/crypto" "github.com/KenshiTech/unchained/internal/crypto/bls" "github.com/KenshiTech/unchained/internal/datasets" "github.com/KenshiTech/unchained/internal/log" @@ -43,7 +44,7 @@ func CorrectnessRecord(conn *websocket.Conn, payload []byte) ([]byte, error) { return []byte{}, constants.ErrCantVerifyBls } - ok, err = bls.Verify(signature, hash, pk) + ok, err = crypto.Identity.Bls.Verify(signature, hash, pk) if err != nil { log.Logger.With("Error", err).Error("Can't verify bls") return []byte{}, constants.ErrCantVerifyBls diff --git a/internal/transport/server/websocket/handler/event.go b/internal/transport/server/websocket/handler/event.go index e5ceb176..c9cffc42 100644 --- a/internal/transport/server/websocket/handler/event.go +++ b/internal/transport/server/websocket/handler/event.go @@ -2,6 +2,7 @@ package handler import ( "github.com/KenshiTech/unchained/internal/constants" + "github.com/KenshiTech/unchained/internal/crypto" "github.com/KenshiTech/unchained/internal/crypto/bls" "github.com/KenshiTech/unchained/internal/datasets" "github.com/KenshiTech/unchained/internal/log" @@ -43,7 +44,7 @@ func EventLog(conn *websocket.Conn, payload []byte) ([]byte, error) { return []byte{}, constants.ErrCantVerifyBls } - ok, err = bls.Verify(signature, hash, pk) + ok, err = crypto.Identity.Bls.Verify(signature, hash, pk) if err != nil { log.Logger.Error("Can't recover bls pub-key: %v", err) return []byte{}, constants.ErrCantVerifyBls diff --git a/internal/transport/server/websocket/handler/price.go b/internal/transport/server/websocket/handler/price.go index 7a1f3a74..c0381328 100644 --- a/internal/transport/server/websocket/handler/price.go +++ b/internal/transport/server/websocket/handler/price.go @@ -2,6 +2,7 @@ package handler import ( "github.com/KenshiTech/unchained/internal/constants" + "github.com/KenshiTech/unchained/internal/crypto" "github.com/KenshiTech/unchained/internal/crypto/bls" "github.com/KenshiTech/unchained/internal/datasets" "github.com/KenshiTech/unchained/internal/log" @@ -43,7 +44,7 @@ func PriceReport(conn *websocket.Conn, payload []byte) ([]byte, error) { return []byte{}, constants.ErrInternalError } - ok, err = bls.Verify(signature, hash, pk) + ok, err = crypto.Identity.Bls.Verify(signature, hash, pk) if err != nil { log.Logger.Error("Can't recover bls pub-key: %v", err) return []byte{}, constants.ErrCantVerifyBls diff --git a/main.go b/main.go deleted file mode 100644 index ff57ba07..00000000 --- a/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/KenshiTech/unchained/internal/cmd" - -func main() { - cmd.Execute() -} diff --git a/zk/.gitignore b/zk/.gitignore deleted file mode 100644 index 4521c278..00000000 --- a/zk/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.bin -*.sol -bin diff --git a/zk/Makefile b/zk/Makefile deleted file mode 100644 index 90e7dccb..00000000 --- a/zk/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -zk: - GOOS=windows GOARCH=amd64 go build -o bin/zk.windows.amd64.exe main.go - GOOS=darwin GOARCH=amd64 go build -o bin/zk.darwin.amd64 main.go - GOOS=darwin GOARCH=arm64 go build -o bin/zk.darwin.arm64 main.go - GOOS=linux GOARCH=amd64 go build -o bin/zk.linux.amd64 main.go - GOOS=linux GOARCH=arm64 go build -o bin/zk.linux.arm64 main.go diff --git a/zk/go.mod b/zk/go.mod deleted file mode 100644 index 4e2f9c34..00000000 --- a/zk/go.mod +++ /dev/null @@ -1,33 +0,0 @@ -module unchained-zk - -go 1.21.5 - -require ( - github.com/consensys/gnark v0.9.1 - github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb - github.com/urfave/cli/v2 v2.26.0 -) - -require ( - github.com/bits-and-blooms/bitset v1.8.0 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect - github.com/consensys/bavard v0.1.13 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fxamacker/cbor/v2 v2.5.0 // indirect - github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rs/zerolog v1.30.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect - github.com/x448/float16 v0.8.4 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/sys v0.11.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - rsc.io/tmplfunc v0.0.3 // indirect -) diff --git a/zk/go.sum b/zk/go.sum deleted file mode 100644 index 3b7ae188..00000000 --- a/zk/go.sum +++ /dev/null @@ -1,78 +0,0 @@ -github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= -github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark v0.9.1 h1:aTwBp5469MY/2jNrf4ABrqHRW3+JytfkADdw4ZBY7T0= -github.com/consensys/gnark v0.9.1/go.mod h1:udWvWGXnfBE7mn7BsNoGAvZDnUhcONBEtNijvVjfY80= -github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb h1:f0BMgIjhZy4lSRHCXFbQst85f5agZAjtDMixQqBWNpc= -github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= -github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI= -github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/zk/lib/bls.go b/zk/lib/bls.go deleted file mode 100644 index fdae33cb..00000000 --- a/zk/lib/bls.go +++ /dev/null @@ -1,63 +0,0 @@ -package lib - -import ( - "crypto/rand" - "math/big" - - bls12_381_ecc "github.com/consensys/gnark-crypto/ecc/bls12-381" - bls12_381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" -) - -var ( - g2Gen bls12_381_ecc.G2Affine -) - -func init() { - _, _, _, g2Gen = bls12_381_ecc.Generators() -} - -// generate BLS private and public key pair -func GenerateKeyPair() (*big.Int, *bls12_381_ecc.G2Affine, error) { - // generate a random point in G2 - g2Order := bls12_381_fr.Modulus() - sk, err := rand.Int(rand.Reader, g2Order) - if err != nil { - return nil, nil, err - } - - pk := new(bls12_381_ecc.G2Affine).ScalarMultiplication(&g2Gen, sk) - - return sk, pk, nil -} - -func Verify( - signature bls12_381_ecc.G1Affine, - g2Gen bls12_381_ecc.G2Affine, - hashedMessage bls12_381_ecc.G1Affine, - publicKey bls12_381_ecc.G2Affine) (bool, error) { - - pairingSigG2, _ := bls12_381_ecc.Pair( - []bls12_381_ecc.G1Affine{signature}, - []bls12_381_ecc.G2Affine{g2Gen}) - - pairingHmPk, pairingError := bls12_381_ecc.Pair( - []bls12_381_ecc.G1Affine{hashedMessage}, - []bls12_381_ecc.G2Affine{publicKey}) - - ok := pairingSigG2.Equal(&pairingHmPk) - - return ok, pairingError -} - -func FastVerify( - signature bls12_381_ecc.G1Affine, - g2Gen bls12_381_ecc.G2Affine, - invertedHashedMessage bls12_381_ecc.G1Affine, - publicKey bls12_381_ecc.G2Affine) (bool, error) { - - ok, pairingError := bls12_381_ecc.PairingCheck( - []bls12_381_ecc.G1Affine{signature, invertedHashedMessage}, - []bls12_381_ecc.G2Affine{g2Gen, publicKey}) - - return ok, pairingError -} diff --git a/zk/lib/cli.go b/zk/lib/cli.go deleted file mode 100644 index 93a94e88..00000000 --- a/zk/lib/cli.go +++ /dev/null @@ -1,160 +0,0 @@ -package lib - -import ( - "fmt" - "os" - - "github.com/consensys/gnark-crypto/ecc" - bls12_381_ecc "github.com/consensys/gnark-crypto/ecc/bls12-381" - "github.com/consensys/gnark/backend/groth16" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/frontend/cs/r1cs" - "github.com/consensys/gnark/std/algebra/emulated/sw_bls12381" - - "github.com/urfave/cli/v2" -) - -func CompileCommand(cCtx *cli.Context) error { - // compiles our circuit into a R1CS - var circuit Circuit - ccs, _ := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) - - // groth16 zkSNARK: Setup - pk, vk, _ := groth16.Setup(ccs) - - // Generate Solidity file - f, _ := os.Create("contract_g16.sol") - exportErr := vk.ExportSolidity(f) - - if exportErr != nil { - fmt.Println(exportErr) - return exportErr - } - - f, _ = os.Create("ccs.bin") - _, exportErr = ccs.WriteTo(f) - - if exportErr != nil { - fmt.Println(exportErr) - return exportErr - } - - f, _ = os.Create("pk.bin") - _, exportErr = pk.WriteTo(f) - - if exportErr != nil { - fmt.Println(exportErr) - return exportErr - } - - f, _ = os.Create("vk.bin") - _, exportErr = vk.WriteTo(f) - - if exportErr != nil { - fmt.Println(exportErr) - return exportErr - } - - return nil -} - -func TestCommand(cCtx *cli.Context) error { - secretKey, publicKey, _ := GenerateKeyPair() - message := []byte("Test message") - dst := []byte("UNCHAINED") - - hashedMessage, _ := bls12_381_ecc.HashToG1(message, dst) - signature := new(bls12_381_ecc.G1Affine).ScalarMultiplication(&hashedMessage, secretKey) - - ok, pairingError := Verify(*signature, g2Gen, hashedMessage, *publicKey) - - if ok { - fmt.Println("✅ First test passes") - } else { - fmt.Println("❌ First test fails") - return pairingError - } - - // Alternate verify why no work? - - var invertedHm bls12_381_ecc.G1Affine - invertedHm.Neg(&hashedMessage) // Inverting hm for the pairing - - ok, pairingError = FastVerify(*signature, g2Gen, invertedHm, *publicKey) - - // This one doesn't pass! - if ok { - fmt.Println("✅ Second test passes") - } else { - fmt.Println("❌ Second test fails") - return pairingError - } - - // compiles our circuit into a R1CS - ccs := groth16.NewCS(ecc.BN254) - f, openErr := os.Open("ccs.bin") - - if openErr != nil { - fmt.Println("❌ Cannot open the circuit") - return openErr - } - - _, readErr := ccs.ReadFrom(f) - - if readErr != nil { - fmt.Println("❌ Cannot read the circuit") - return readErr - } - - // groth16 zkSNARK: Setup - pk := groth16.NewProvingKey(ecc.BN254) - vk := groth16.NewVerifyingKey(ecc.BN254) - - f, openErr = os.Open("pk.bin") - - if openErr != nil { - fmt.Println("❌ Cannot open the proving key") - return openErr - } - - _, readErr = pk.ReadFrom(f) - - if readErr != nil { - fmt.Println("❌ Cannot read the proving key") - return readErr - } - - f, openErr = os.Open("vk.bin") - - if openErr != nil { - fmt.Println("❌ Cannot open the verifying key") - return openErr - } - - _, readErr = vk.ReadFrom(f) - - if readErr != nil { - fmt.Println("Cannot read the verifying key") - return readErr - } - - // witness definition - assignment := Circuit{ - Sig: sw_bls12381.NewG1Affine(*signature), - G2: sw_bls12381.NewG2Affine(g2Gen), - Hm: sw_bls12381.NewG1Affine(invertedHm), - Pk: sw_bls12381.NewG2Affine(*publicKey)} - - witness, _ := frontend.NewWitness(&assignment, ecc.BN254.ScalarField()) - publicWitness, _ := witness.Public() - - // groth16: Prove & Verify - proof, _ := groth16.Prove(ccs, pk, witness) - err := groth16.Verify(proof, vk, publicWitness) - - if err != nil { - return err - } - - return nil -} diff --git a/zk/lib/zk.go b/zk/lib/zk.go deleted file mode 100644 index 4ded96bf..00000000 --- a/zk/lib/zk.go +++ /dev/null @@ -1,35 +0,0 @@ -package lib - -import ( - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/algebra/emulated/sw_bls12381" -) - -// Boneh-Lynn-Shacham (BLS) signature verification -// e(sig, g2) * e(hm, pk) == 1 -// where: -// - Sig (in G1) the signature -// - G2 (in G2) the public generator of G2 -// - Hm (in G1) the hashed-to-curve message -// - Pk (in G2) the public key of the signer -type Circuit struct { - Sig sw_bls12381.G1Affine - G2 sw_bls12381.G2Affine - Hm sw_bls12381.G1Affine - Pk sw_bls12381.G2Affine -} - -func (circuit *Circuit) Define(api frontend.API) error { - - pairing, _ := sw_bls12381.NewPairing(api) - - err := sw_bls12381.Pairing.PairingCheck(*pairing, - []*sw_bls12381.G1Affine{&circuit.Sig, &circuit.Hm}, - []*sw_bls12381.G2Affine{&circuit.G2, &circuit.Pk}) - - if err != nil { - return err - } - - return nil -} diff --git a/zk/main.go b/zk/main.go deleted file mode 100644 index 9ed8a775..00000000 --- a/zk/main.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "log" - "os" - "unchained-zk/lib" - - "github.com/urfave/cli/v2" -) - -func main() { - - app := cli.App{ - Name: "unchained-zk", - Usage: "Unchained zk-SNARKs toolkit", - Commands: []*cli.Command{ - { - Name: "compile", - Aliases: []string{"c"}, - Usage: "Compile the zk-SNARKs circuit", - Action: lib.CompileCommand, - }, - { - Name: "test", - Aliases: []string{"t"}, - Usage: "Run a test on the zk-SNARKs circuit", - Action: lib.TestCommand, - }, - }, - } - - if err := app.Run(os.Args); err != nil { - log.Fatal(err) - } -}