diff --git a/.gitignore b/.gitignore index 4a3cde9d..b6a9e3d3 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ bin/* # Output of the go coverage tool, specifically when used with LiteIDE *.out +main +.vscode +*.log \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 00000000..e0f35ea2 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "os" + + "github.com/iotexproject/iotex-core/pkg/log" + "github.com/urfave/cli/v2" + "go.uber.org/zap" + + "github.com/iotexproject/iotex-analytics/cmd/server" +) + +var ( + version = "0.1.0-dev" +) + +func main() { + app := cli.NewApp() + app.Name = "iotex-analytics" + app.Usage = "iotex-analytics is Analytics Platform for Iotex Smart Chain" + app.Version = version + app.Commands = []*cli.Command{ + server.Commands, + } + if err := app.Run(os.Args); err != nil { + log.L().Fatal("Failed to start application", zap.Error(err)) + } +} diff --git a/cmd/server/server.go b/cmd/server/server.go new file mode 100644 index 00000000..c4cae7ed --- /dev/null +++ b/cmd/server/server.go @@ -0,0 +1,127 @@ +package server + +import ( + "context" + "fmt" + "os" + "os/signal" + "time" + + "github.com/iotexproject/iotex-analytics/config" + "github.com/iotexproject/iotex-analytics/indexer" + "github.com/iotexproject/iotex-analytics/indexservice" + "github.com/iotexproject/iotex-analytics/sql" + "github.com/iotexproject/iotex-core/action/protocol" + "github.com/iotexproject/iotex-core/blockchain/blockdao" + "github.com/iotexproject/iotex-core/blockchain/genesis" + "github.com/iotexproject/iotex-core/pkg/log" + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/urfave/cli/v2" + "go.uber.org/zap" + "google.golang.org/grpc" +) + +var Commands = &cli.Command{ + Name: "server", + Usage: "start server", + Description: `start server`, + Action: runServer, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "config", + Aliases: []string{"c"}, + Value: config.FindDefaultConfigPath(), + Usage: "Load configuration from `FILE`", + }, + }, +} + +func runServer(c *cli.Context) error { + var err error + var cfg *config.Config + if c.String("config") == "" { + log.L().Fatal("Cannot determine default configuration path.", + zap.Any("DefaultConfigFiles", config.DefaultConfigFiles), + zap.Any("DefaultConfigDirs", config.DefaultConfigDirs)) + } + + cfg, err = config.New(c.String("config")) + if err != nil { + return err + } + if err := log.InitLoggers(cfg.Log, cfg.SubLogs); err != nil { + fmt.Fprintf(os.Stderr, "ERROR: Failed to init logger: %v\n", err) + os.Exit(1) + } + + store := sql.CreateMySQLStore( + cfg.Mysql.UserName, + cfg.Mysql.Password, + cfg.Mysql.Host, + cfg.Mysql.Port, + cfg.Mysql.DBName, + ) + go func() { + if err := store.Start(c.Context); err != nil { + log.L().Fatal("Failed to start mysql store", zap.Error(err)) + } + }() + ctx := sql.WithStore(c.Context, store) + + grpcCtx1, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + conn1, err := grpc.DialContext(grpcCtx1, cfg.Iotex.ChainEndPoint, grpc.WithBlock(), grpc.WithInsecure()) + if err != nil { + log.L().Error("Failed to connect to chain's API server.") + } + chainClient := iotexapi.NewAPIServiceClient(conn1) + + var indexers []blockdao.BlockIndexer + var dao blockdao.BlockDAO + if false { + dao = blockdao.NewBlockDAOInMemForTest(indexers) + } else { + dao = blockdao.NewBlockDAO(indexers, cfg.BlockDB) + } + var tip protocol.TipInfo + ctx = protocol.WithBlockchainCtx( + ctx, + protocol.BlockchainCtx{ + Genesis: genesis.Default, + Tip: tip, + }, + ) + var asyncindexers []indexer.AsyncIndexer + + asyncindexers = append(asyncindexers, indexer.NewBlockIndexer(store)) + ids := indexservice.NewIndexService(chainClient, 64, dao, asyncindexers) + go func() { + if err := ids.Start(ctx); err != nil { + log.L().Fatal("Failed to start the indexer", zap.Error(err)) + } + }() + handleShutdown(store, ids) + + return nil +} + +type Stopper interface { + Stop(context.Context) error +} + +func handleShutdown(service ...Stopper) { + stop := make(chan os.Signal) + signal.Notify(stop, os.Interrupt, os.Kill) + + // wait INT or KILL + <-stop + log.L().Info("shutting down ...") + ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) + defer cancel() + for _, s := range service { + if err := s.Stop(ctx); err != nil { + log.L().Error("shutdown", zap.Error(err)) + } + } + return +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 00000000..df592344 --- /dev/null +++ b/config/config.go @@ -0,0 +1,113 @@ +package config + +import ( + "io/ioutil" + "os" + "path/filepath" + + coreconfig "github.com/iotexproject/iotex-core/config" + "github.com/iotexproject/iotex-core/pkg/log" + homedir "github.com/mitchellh/go-homedir" + "github.com/pkg/errors" + "gopkg.in/yaml.v2" +) + +var ( + // Default is the default config + Default = Config{ + Server: Server{ + Host: "127.0.0.1", + Port: "8113", + }, + BlockDB: coreconfig.DB{ + NumRetries: 3, + MaxCacheSize: 64, + BlockStoreBatchSize: 16, + V2BlocksToSplitDB: 1000000, + Compressor: "Snappy", + CompressLegacy: false, + SplitDBSizeMB: 0, + SplitDBHeight: 900000, + HistoryStateRetention: 2000, + }, + SubLogs: make(map[string]log.GlobalConfig), + } +) + +type ( + Server struct { + Host string `yaml:"host"` + Port string `yaml:"port"` + } + Mysql struct { + DBName string `yaml:"dbname"` + UserName string `yaml:"username"` + Password string `yaml:"password"` + Host string `yaml:"host"` + Port string `yaml:"port"` + } + Iotex struct { + ChainEndPoint string `yaml:"chainEndPoint"` + } + Config struct { + Server Server `yaml:"server"` + Mysql Mysql `yaml:"mysql"` + Iotex Iotex `yaml:"iotex"` + BlockDB coreconfig.DB `yaml:"blockDB"` + Log log.GlobalConfig `yaml:"log"` + SubLogs map[string]log.GlobalConfig `yaml:"subLogs" json:"subLogs"` + } +) + +func New(path string) (cfg *Config, err error) { + body, err := ioutil.ReadFile(path) + if err != nil { + return cfg, errors.Wrap(err, "failed to read config content") + } + cfg = &Default + if err = yaml.Unmarshal(body, cfg); err != nil { + return cfg, errors.Wrap(err, "failed to unmarshal config to struct") + } + return +} + +var ( + // File names from which we attempt to read configuration. + DefaultConfigFiles = []string{"config.yml", "config.yaml"} + + // Launchd doesn't set root env variables, so there is default + DefaultConfigDirs = []string{"~/.iotex-analytics", "/usr/local/etc/iotex-analytics", "/etc/iotex-analytics"} +) + +// FileExists checks to see if a file exist at the provided path. +func FileExists(path string) (bool, error) { + f, err := os.Open(path) + if err != nil { + if os.IsNotExist(err) { + // ignore missing files + return false, nil + } + return false, err + } + f.Close() + return true, nil +} + +// FindDefaultConfigPath returns the first path that contains a config file. +// If none of the combination of DefaultConfigDirs and DefaultConfigFiles +// contains a config file, return empty string. +func FindDefaultConfigPath() string { + for _, configDir := range DefaultConfigDirs { + for _, configFile := range DefaultConfigFiles { + dirPath, err := homedir.Expand(configDir) + if err != nil { + continue + } + path := filepath.Join(dirPath, configFile) + if ok, _ := FileExists(path); ok { + return path + } + } + } + return "" +} diff --git a/config_new.yaml b/config_new.yaml new file mode 100644 index 00000000..e589fae9 --- /dev/null +++ b/config_new.yaml @@ -0,0 +1,23 @@ +server: + port: 8883 +mysql: + host: 127.0.0.1 + port: 3306 + username: root + password: root + dbname: iotex_analytics +iotex: + chainEndPoint: api.testnet.iotex.one:80 +blockDB: + dbPath: chain.db +log: + zap: + development: true + level: debug + encoding: console + disableCaller: true + disableStacktrace: false + outputPaths: ["stdout"] + errorOutputPaths: ["stderr"] + stderrRedirectFile: error.log + stdLogRedirect: false \ No newline at end of file diff --git a/go.mod b/go.mod index 907f09c3..a8170815 100644 --- a/go.mod +++ b/go.mod @@ -9,22 +9,24 @@ require ( github.com/ethereum/go-ethereum v1.9.5 github.com/go-sql-driver/mysql v1.4.1 github.com/golang/mock v1.4.4 - github.com/golang/protobuf v1.4.2 - github.com/iotexproject/go-pkgs v0.1.2-0.20200523040337-5f1d9ddaa8ee - github.com/iotexproject/iotex-address v0.2.2 - github.com/iotexproject/iotex-core v1.1.3 + github.com/golang/protobuf v1.4.3 + github.com/iotexproject/go-pkgs v0.1.5-0.20210105202208-2dc9b27250a6 + github.com/iotexproject/iotex-address v0.2.4 + github.com/iotexproject/iotex-core v1.1.4-0.20210309070336-f9809474d1f4 github.com/iotexproject/iotex-election v0.3.5-0.20201031050050-c3ab4f339a54 - github.com/iotexproject/iotex-proto v0.4.4-0.20201029172022-a8466422b0f1 + github.com/iotexproject/iotex-proto v0.4.7 + github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.3.0 github.com/rs/zerolog v1.18.0 - github.com/stretchr/testify v1.5.1 + github.com/stretchr/testify v1.6.1 + github.com/urfave/cli/v2 v2.3.0 github.com/vektah/gqlparser v1.1.2 go.uber.org/zap v1.10.0 - golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e + golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566 // indirect - google.golang.org/grpc v1.28.0 - gopkg.in/yaml.v2 v2.2.8 + google.golang.org/grpc v1.33.1 + gopkg.in/yaml.v2 v2.4.0 ) replace github.com/ethereum/go-ethereum => github.com/iotexproject/go-ethereum v0.3.1 diff --git a/go.sum b/go.sum index 42f4bd3e..098fa684 100644 --- a/go.sum +++ b/go.sum @@ -35,13 +35,13 @@ github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2uc github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apilayer/freegeoip v3.5.0+incompatible h1:z1u2gv0/rsSi/HqMDB436AiUROXXim7st5DOg4Ikl4A= github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU= github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= github.com/aristanetworks/goarista v0.0.0-20190429220743-799535f6f364/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= -github.com/aristanetworks/goarista v0.0.0-20190531155855-fef20d617fa7 h1:95vZEj9fXZGLEfElWj3L0Wkv1eaeV92xZHBCL89+K4A= github.com/aristanetworks/goarista v0.0.0-20190531155855-fef20d617fa7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20190912214011-b54698eaaca6 h1:6bZNnQcA2fkzH9AhZXbp2nDqbWa4bBqFeUb70Zq1HBM= github.com/aristanetworks/goarista v0.0.0-20190912214011-b54698eaaca6/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns= @@ -50,14 +50,12 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.0.0-20190427004231-96897255fd17 h1:m0N5Vg5nP3zEz8TREZpwX3gt4Biw3/8fbIf4A3hO96g= github.com/btcsuite/btcd v0.0.0-20190427004231-96897255fd17/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= @@ -70,7 +68,6 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/bwmarrin/discordgo v0.19.0 h1:kMED/DB0NR1QhRcalb85w0Cu3Ep2OrGAqZH1R5awQiY= github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -91,6 +88,8 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -114,19 +113,19 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo= github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= +github.com/elastic/gosigar v0.12.0 h1:AsdhYCJlTudhfOYQyFNgx+fIVTfrDO0V1ST0vHgiapU= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -135,12 +134,10 @@ github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJY github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -151,26 +148,20 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -179,18 +170,18 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26 h1:lMm2hD9Fy0ynom5+85/pbdkiYcBqM1JWmhpAXLmy0fw= +github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -200,8 +191,9 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -210,21 +202,19 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51 github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20190610161739-8f92f34fc598 h1:XLoCW/kXxbvPvp216Kq/c+TtwWYHy9sjeDidFcG45g0= github.com/graph-gophers/graphql-go v0.0.0-20190610161739-8f92f34fc598/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg= github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.14.5 h1:aiLxiiVzAXb7wb3lAmubA69IokWOoUNe+E7TdGKh8yw= github.com/grpc-ecosystem/grpc-gateway v1.14.5/go.mod h1:UJ0EZAp832vCd54Wev9N1BMKEyvcZ5+IM0AwDrnlkEc= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -241,7 +231,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -252,7 +241,6 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/howeyc/fsnotify v0.9.0 h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY= github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= @@ -269,20 +257,24 @@ github.com/iotexproject/go-p2p v0.2.12 h1:xLn8RVDZjMDbupMxGClp5sO+fPBesvFg+uNgRs github.com/iotexproject/go-p2p v0.2.12/go.mod h1:RDVrUSjtHO5G/h1uhPfILcOqR7gRVPYvFnrc2kHyQek= github.com/iotexproject/go-pkgs v0.1.1/go.mod h1:U3Mb0Wm6XtYpFRODg3pe34DEaWhFwqI2Q5xZK6hji2I= github.com/iotexproject/go-pkgs v0.1.2-0.20200212033110-8fa5cf96fc1b/go.mod h1:vP6jDCmhY5F4jtWD1hf1BTlY5hu+0q0oqALfBL7pY+k= -github.com/iotexproject/go-pkgs v0.1.2-0.20200523040337-5f1d9ddaa8ee h1:LxYC2EoAgk2BeFJJ6kdXiTLZxAo7LXG1cdNT4yG8GvY= -github.com/iotexproject/go-pkgs v0.1.2-0.20200523040337-5f1d9ddaa8ee/go.mod h1:vP6jDCmhY5F4jtWD1hf1BTlY5hu+0q0oqALfBL7pY+k= +github.com/iotexproject/go-pkgs v0.1.4/go.mod h1:rV7K/DWOrkhi4nrvfPDjaV4J6wyRw21aJfZFXkCKy4s= +github.com/iotexproject/go-pkgs v0.1.5-0.20210105202208-2dc9b27250a6 h1:dWXjh8yirOVlvOx7DRY17RU7CfQjO5mmv7hsnw/QKw0= +github.com/iotexproject/go-pkgs v0.1.5-0.20210105202208-2dc9b27250a6/go.mod h1:kLGqdrZWuX6HbPIf0wwMm8n6Zt/ch479rV1U2qU3LJ4= github.com/iotexproject/iotex-address v0.2.1/go.mod h1:ONmTqmg6zO7VWF9TcWN+UrreFr/xpazlv9PWOALbLFA= -github.com/iotexproject/iotex-address v0.2.2 h1:HCAefeHGdQuCZ5NaHUM+VksuscfSiUfmeM3PtEZqQ+k= -github.com/iotexproject/iotex-address v0.2.2/go.mod h1:dHaK1u8jvrlLqxmYzrt65wXKsL80mjAPBPyJIQrKFUA= -github.com/iotexproject/iotex-antenna-go/v2 v2.4.0 h1:NcEYgkmT28uEykC9aYFB4U5eEbNu+ZX5bqi2eLvAXWg= +github.com/iotexproject/iotex-address v0.2.3/go.mod h1:K78yPSMB4K7gF/iQ7djT1amph0RBrP3rSkFfH7gNG70= +github.com/iotexproject/iotex-address v0.2.4 h1:qrkM+X6Z6Rljto1KH8ZgAUrnzU5AqMqN0OCXcQEauS4= +github.com/iotexproject/iotex-address v0.2.4/go.mod h1:K78yPSMB4K7gF/iQ7djT1amph0RBrP3rSkFfH7gNG70= github.com/iotexproject/iotex-antenna-go/v2 v2.4.0/go.mod h1:gN2/O/8/Up1AqocrntePkgbHQSxAFyq5o+LUi4x4r9Q= -github.com/iotexproject/iotex-core v1.1.3 h1:PC2QFyl1QOOkGpURSMvU56KF9+EYa3BD+LQDSCR5KXQ= -github.com/iotexproject/iotex-core v1.1.3/go.mod h1:aEPccIcwdySVHXodSBlorRA7t91jQt8IewBepPWNeB0= +github.com/iotexproject/iotex-antenna-go/v2 v2.4.2-0.20201211202736-96d536a425fe h1:3ZoCWB1oguKwsaQDdofhrnLu5TQqQfNv4EgFDfGSe7g= +github.com/iotexproject/iotex-antenna-go/v2 v2.4.2-0.20201211202736-96d536a425fe/go.mod h1:uHaU3caCfeOlWav8D2uAbAAFO/YEKQVZhY3eUU1z0d0= +github.com/iotexproject/iotex-core v1.1.4-0.20210309070336-f9809474d1f4 h1:a3nrNa1jqDN8yM+Na2aqBIaVjgKW8FDNI7le+6mBtMU= +github.com/iotexproject/iotex-core v1.1.4-0.20210309070336-f9809474d1f4/go.mod h1:WAPYyr0wDt1/NwV2Lex2LxhagKvcqdG8SLS8oLTAb8Y= github.com/iotexproject/iotex-election v0.3.5-0.20201031050050-c3ab4f339a54 h1:nUHBrG5mlqxWzv/wjOkv8M7cwi5uTjZjSqLpo26HS00= github.com/iotexproject/iotex-election v0.3.5-0.20201031050050-c3ab4f339a54/go.mod h1:rA7Vl9hDRRb3qYUuwH4ywMKsITjO5J1ThyLWoA+VQ2U= github.com/iotexproject/iotex-proto v0.4.0/go.mod h1:SttnbjoUJKHuKtDxCDJ5ewziAY4XrMPE2wo++Xod4b0= -github.com/iotexproject/iotex-proto v0.4.4-0.20201029172022-a8466422b0f1 h1:arzcxsl3VzUnrx6qFtV0tbou575YXvIlPbqm1q+DZlU= github.com/iotexproject/iotex-proto v0.4.4-0.20201029172022-a8466422b0f1/go.mod h1:VamfHxZ58AbpWJumRIE/u9tt/TouIlDkzk0dazVKKRY= +github.com/iotexproject/iotex-proto v0.4.7 h1:K75GrFTigwqymYaTUIq3cuH0BB/MTpAfXFcwED1TTio= +github.com/iotexproject/iotex-proto v0.4.7/go.mod h1:Xg6REkv+nTZN+OC22xXIQuqKdTWWHwOAJEXCoMpDwtI= github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -459,8 +451,9 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -478,6 +471,7 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= @@ -514,16 +508,22 @@ github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.0.2 h1:uWy8f8Icfo9t/U80+CR5oqM84gSgNqh8xLB7rVslfcw= github.com/multiformats/go-multistream v0.0.2/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= @@ -582,6 +582,7 @@ github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSg github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= +github.com/rodaine/table v1.0.1/go.mod h1:UVEtfBsflpeEcD56nF4F5AocNFta0ZuolpSVdPtlmP4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -591,6 +592,7 @@ github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.18.0 h1:CbAm3kP2Tptby1i9sYy2MGRg0uxIN9cyDb59Ys7W8z8= github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -599,6 +601,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -632,13 +635,13 @@ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v0.0.0-20180621010148-0d5a0ceb10cf/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs= -github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= +github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= +github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= @@ -648,6 +651,8 @@ github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1 github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/vektah/dataloaden v0.2.0/go.mod h1:vxM6NuRlgiR0M6wbVTJeKp9vQIs81ZMfCYO+4yq/jbE= github.com/vektah/gqlparser v1.1.2 h1:ZsyLGn7/7jDNI+y4SEhI4yAxRChlv15pUHMjijT+e68= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= @@ -769,18 +774,25 @@ golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -805,18 +817,26 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -850,8 +870,9 @@ golang.org/x/xerrors v0.0.0-20190212162355-a5947ffaace3/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20190528162220-0421b64034aa/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -874,8 +895,10 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a h1:GnJAhasbD8HiT8DZMvsEx3QLVy/X0icq/MGr0MqRJ2M= +google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -885,8 +908,8 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -895,6 +918,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -904,7 +928,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= @@ -928,8 +951,12 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/indexer/blockindexer.go b/indexer/blockindexer.go new file mode 100644 index 00000000..74d2aeca --- /dev/null +++ b/indexer/blockindexer.go @@ -0,0 +1,76 @@ +package indexer + +import ( + "context" + + s "github.com/iotexproject/iotex-analytics/sql" + "github.com/iotexproject/iotex-core/blockchain/block" + "github.com/iotexproject/iotex-core/pkg/log" + "go.uber.org/zap" +) + +/** + block table +CREATE TABLE `block_history` ( + `epoch_number` decimal(65,0) NOT NULL, + `block_height` decimal(65,0) NOT NULL, + `block_hash` varchar(64) NOT NULL, + `gas_consumed` decimal(65,0) NOT NULL, + `producer_address` varchar(41) NOT NULL, + `producer_name` varchar(24) NOT NULL, + `expected_producer_address` varchar(41) NOT NULL, + `expected_producer_name` varchar(24) NOT NULL, + `timestamp` decimal(65,0) NOT NULL, + PRIMARY KEY (`block_height`), + KEY `block_height_index` (`block_height`), + KEY `epoch_producer_index` (`epoch_number`,`producer_name`,`expected_producer_name`), + KEY `timestamp_index` (`timestamp`), + KEY `epoch_number_index` (`epoch_number`), + KEY `expected_producer_name_index` (`expected_producer_name`), + KEY `expected_producer_address_index` (`expected_producer_address`), + KEY `producer_name_index` (`producer_name`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +*/ + +type blockIndexer struct { + iht *IndexHeightTable + log *zap.Logger +} + +// NewBlockIndexer returns the +func NewBlockIndexer(store s.Store) AsyncIndexer { + return &blockIndexer{ + iht: &IndexHeightTable{ + Name: "blockindexer", + }, + log: log.Logger("blockindexer"), + } +} + +func (bi *blockIndexer) Start(ctx context.Context) error { + bi.log.Debug("blockindex start") + + return bi.iht.Init(ctx) +} + +func (bi *blockIndexer) Stop(ctx context.Context) error { + bi.log.Debug("blockindex stop") + + return nil +} + +func (bi *blockIndexer) NextHeight(ctx context.Context) (uint64, error) { + height, err := bi.iht.Height(ctx) + if err != nil { + return 0, err + } + nextHeight := height + 1 + bi.log.Debug("blockIndexer nextHeight", zap.Uint64("nextHeight", nextHeight)) + return nextHeight, nil +} + +func (bi *blockIndexer) PutBlock(ctx context.Context, blk *block.Block) error { + bi.iht.Upsert(ctx, blk.Height()) + bi.log.Debug("blockindexer putblock", zap.Any("block", blk)) + return nil +} diff --git a/indexer/indexer.go b/indexer/indexer.go new file mode 100644 index 00000000..03a99064 --- /dev/null +++ b/indexer/indexer.go @@ -0,0 +1,17 @@ +package indexer + +import ( + "context" + + "github.com/iotexproject/iotex-core/blockchain/block" +) + +type ( + // AsyncIndexer is the interface of an async indexer of analytics + AsyncIndexer interface { + Start(context.Context) error + Stop(context.Context) error + NextHeight(context.Context) (uint64, error) + PutBlock(context.Context, *block.Block) error + } +) diff --git a/indexer/indexerheighttable.go b/indexer/indexerheighttable.go new file mode 100644 index 00000000..99d5a01e --- /dev/null +++ b/indexer/indexerheighttable.go @@ -0,0 +1,75 @@ +package indexer + +import ( + "context" + "database/sql" + + s "github.com/iotexproject/iotex-analytics/sql" +) + +/* +CREATE TABLE `index_heights` ( + `name` varchar(128) NOT NULL, + `height` bigint(20) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +*/ +type IndexHeightTable struct { + Name string +} + +func (iht *IndexHeightTable) Init(ctx context.Context) error { + height, err := iht.Height(ctx) + if err != nil && err != sql.ErrNoRows { + return err + } + if height == 0 { + return iht.Upsert(ctx, 0) + } + return nil +} + +func (iht *IndexHeightTable) Upsert(ctx context.Context, height uint64) error { + tx, ok := s.ExtractTx(ctx) + if ok { + return upsert(tx, iht.Name, height) + } + store, ok := s.ExtractStore(ctx) + if !ok { + return s.ErrNoStoreContext + } + return store.Transact(func(tx *sql.Tx) error { + return upsert(tx, iht.Name, height) + }) +} + +func upsert(tx *sql.Tx, name string, height uint64) error { + if _, err := tx.Exec("INSERT IGNORE INTO index_heights (`name`, `height`) VALUES (?, 0)", name); err != nil { + return err + } + _, err := tx.Exec("UPDATE index_heights SET `height` = ? WHERE `name` = ? AND `height` < ?", height, name, height) + + return err +} + +func (iht *IndexHeightTable) Height(ctx context.Context) (uint64, error) { + var row *sql.Row + tx, ok := s.ExtractTx(ctx) + if ok { + row = tx.QueryRow("SELECT height FROM index_heights WHERE name = ?", iht.Name) + } else { + store, ok := s.ExtractStore(ctx) + if !ok { + return 0, s.ErrNoStoreContext + } + row = store.GetDB().QueryRow("SELECT height FROM index_heights WHERE name = ?", iht.Name) + } + var h sql.NullInt64 + if err := row.Scan(&h); err != nil { + return 0, err + } + if !h.Valid { + return 0, nil + } + return uint64(h.Int64), nil +} diff --git a/indexservice/indexservice.go b/indexservice/indexservice.go new file mode 100644 index 00000000..52141405 --- /dev/null +++ b/indexservice/indexservice.go @@ -0,0 +1,255 @@ +package indexservice + +import ( + "context" + "math/big" + "sync" + "sync/atomic" + + "github.com/iotexproject/go-pkgs/hash" + "github.com/iotexproject/iotex-analytics/indexer" + "github.com/iotexproject/iotex-core/action" + "github.com/iotexproject/iotex-core/blockchain/block" + "github.com/iotexproject/iotex-core/blockchain/blockdao" + "github.com/iotexproject/iotex-core/pkg/log" + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/pkg/errors" + "go.uber.org/zap" +) + +type AtomBool struct{ flag int32 } + +func (b *AtomBool) Set(value bool) { + var i int32 = 0 + if value { + i = 1 + } + atomic.StoreInt32(&(b.flag), int32(i)) +} + +func (b *AtomBool) Get() bool { + if atomic.LoadInt32(&(b.flag)) != 0 { + return true + } + return false +} + +type ( + + // IndexService is the main indexer service, which coordinates the building of all indexers + IndexService struct { + dao blockdao.BlockDAO + indexers []indexer.AsyncIndexer + terminate chan bool + wg sync.WaitGroup + subscribers []chan uint64 + indexerLocks []AtomBool + + chainClient iotexapi.APIServiceClient + batchSize uint64 + } +) + +// NewIndexService creates a new indexer service +func NewIndexService(chainClient iotexapi.APIServiceClient, batchSize uint64, bc blockdao.BlockDAO, indexers []indexer.AsyncIndexer) *IndexService { + subscribers := make([]chan uint64, len(indexers)) + for i := range indexers { + subscribers[i] = make(chan uint64, 0) + } + return &IndexService{ + dao: bc, + indexers: indexers, + subscribers: subscribers, + terminate: make(chan bool), + wg: sync.WaitGroup{}, + indexerLocks: make([]AtomBool, len(indexers)), + + chainClient: chainClient, + batchSize: batchSize, + } +} + +func (is *IndexService) startIndex(ctx context.Context, i int) error { + if err := is.indexers[i].Start(ctx); err != nil { + return err + } + is.wg.Add(1) + go func() { + defer is.wg.Done() + for { + select { + case <-is.terminate: + return + case tipHeight := <-is.subscribers[i]: + + if is.indexerLocks[i].Get() { + continue + } + is.indexerLocks[i].Set(true) + + nextHeight, err := is.indexers[i].NextHeight(ctx) + if err != nil { + log.S().Panic("failed to get next height", zap.Error(err)) + } + + for nextHeight < tipHeight { + blk, err := is.dao.GetBlockByHeight(nextHeight) + if err != nil { + log.S().Panicf("failed to read block from dao %v\n", err) + } + receipts, err := is.dao.GetReceipts(nextHeight) + if err != nil { + log.S().Panicf("failed to read receipts from dao %v\n", err) + } + blk.Receipts = receipts + actionReceipts := make(map[hash.Hash256]*action.Receipt, len(receipts)) + for _, receipt := range receipts { + actionReceipts[receipt.ActionHash] = receipt + } + tlogs, err := is.dao.TransactionLogs(nextHeight) + if err != nil { + log.S().Panicf("failed to read transaction logs from dao %v\n", err) + } + for _, l := range tlogs.Logs { + logs := make([]*action.TransactionLog, len(l.Transactions)) + for i, txn := range l.Transactions { + amount, ok := new(big.Int).SetString(txn.Amount, 10) + if !ok { + log.S().Panicf("failed to parse %s\n", txn.Amount) + } + logs[i] = &action.TransactionLog{ + Type: txn.Type, + Amount: amount, + Sender: txn.Sender, + Recipient: txn.Recipient, + } + } + actionReceipts[hash.BytesToHash256(l.ActionHash)].AddTransactionLogs(logs...) + } + if err := is.indexers[i].PutBlock(ctx, blk); err != nil { + log.S().Panicf("failed to put data to indexer %v\n", err) + } + nextHeight++ + } + is.indexerLocks[i].Set(false) + } + } + }() + return nil +} + +// Start starts the index service +func (is *IndexService) Start(ctx context.Context) error { + if err := is.dao.Start(ctx); err != nil { + return err + } + for i := 0; i < len(is.indexers); i++ { + if err := is.startIndex(ctx, i); err != nil { + return err + } + } + go func() { + for { + select { + case <-is.terminate: + return + default: + res, err := is.chainClient.GetChainMeta(ctx, &iotexapi.GetChainMetaRequest{}) + if err != nil { + log.L().Error("failed to get chain meta", zap.Error(err)) + } else { + if err := is.fetchAndBuild(ctx, res.ChainMeta.Height); err != nil { + log.L().Error("failed to index blocks", zap.Error(err)) + } + } + } + } + }() + is.wg.Wait() + + return nil +} + +// Stop stops the index service +func (is *IndexService) Stop(ctx context.Context) error { + close(is.terminate) + for i := 0; i < len(is.indexers); i++ { + if err := is.indexers[i].Stop(ctx); err != nil { + return err + } + } + return is.dao.Stop(ctx) +} + +func (is *IndexService) fetchAndBuild(ctx context.Context, tipHeight uint64) error { + lastHeight, err := is.dao.Height() + if err != nil { + return errors.Wrap(err, "failed to get tip height from block dao") + } + log.L().Debug("fetch height", zap.Uint64("daoHeight", lastHeight), zap.Uint64("tipHeight", tipHeight)) + chainClient := is.chainClient + for startHeight := lastHeight + 1; startHeight <= tipHeight; { + count := is.batchSize + if count > tipHeight-startHeight+1 { + count = tipHeight - startHeight + 1 + } + rawRequest := &iotexapi.GetRawBlocksRequest{ + StartHeight: startHeight, + Count: count, + WithReceipts: true, + } + + getRawBlocksRes, err := chainClient.GetRawBlocks(context.Background(), rawRequest) + if err != nil { + return errors.Wrap(err, "failed to get raw blocks from the chain") + } + for _, blkInfo := range getRawBlocksRes.GetBlocks() { + blk := &block.Block{} + if err := blk.ConvertFromBlockPb(blkInfo.GetBlock()); err != nil { + return errors.Wrap(err, "failed to convert block protobuf to raw block") + } + receipts := map[hash.Hash256]*action.Receipt{} + for _, receiptPb := range blkInfo.GetReceipts() { + receipt := &action.Receipt{} + receipt.ConvertFromReceiptPb(receiptPb) + receipts[receipt.ActionHash] = receipt + blk.Receipts = append(blk.Receipts, receipt) + } + transactionLogs, err := chainClient.GetTransactionLogByBlockHeight( + context.Background(), + &iotexapi.GetTransactionLogByBlockHeightRequest{ + BlockHeight: blk.Header.Height(), + }, + ) + if err != nil { + return errors.Wrap(err, "failed to fetch transaction logs") + } + for _, tlogs := range transactionLogs.TransactionLogs.Logs { + logs := make([]*action.TransactionLog, len(tlogs.Transactions)) + for i, txn := range tlogs.Transactions { + amount, ok := new(big.Int).SetString(txn.Amount, 10) + if !ok { + return errors.Errorf("failed to parse %s", txn.Amount) + } + logs[i] = &action.TransactionLog{ + Type: txn.Type, + Amount: amount, + Sender: txn.Sender, + Recipient: txn.Recipient, + } + } + actHash := hash.BytesToHash256(tlogs.ActionHash) + receipts[actHash].AddTransactionLogs(logs...) + } + if err := is.dao.PutBlock(ctx, blk); err != nil { + return errors.Wrap(err, "failed to build index for the block") + } + blkHeight := blk.Height() + for _, subscriber := range is.subscribers { + subscriber <- blkHeight + } + } + startHeight += count + } + return nil +} diff --git a/sql/mysql.go b/sql/mysql.go index 7b727832..3cb2437e 100644 --- a/sql/mysql.go +++ b/sql/mysql.go @@ -8,6 +8,8 @@ package sql import ( // this is required for mysql usage + "fmt" + _ "github.com/go-sql-driver/mysql" ) @@ -15,3 +17,9 @@ import ( func NewMySQL(connectStr string, dbName string) Store { return newStoreBase("mysql", connectStr, dbName) } + +// CreateMySQLStore instantiates a mysql +func CreateMySQLStore(username, password, host, port, dbName string) Store { + connectStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/", username, password, host, port) + return newStoreBase("mysql", connectStr, dbName) +} diff --git a/sql/rds.go b/sql/rds.go deleted file mode 100644 index e4a77977..00000000 --- a/sql/rds.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2019 IoTeX -// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no -// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent -// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache -// License 2.0 that can be found in the LICENSE file. - -package sql - -import ( - "fmt" - - // we need mysql import because it's called in file, (but compile will complain because there is no display) - _ "github.com/go-sql-driver/mysql" - - "github.com/iotexproject/iotex-core/config" -) - -// NewAwsRDS instantiates an aws rds -func NewAwsRDS(cfg config.RDS) Store { - connectStr := fmt.Sprintf("%s:%s@tcp(%s:%d)/", - cfg.AwsRDSUser, cfg.AwsPass, cfg.AwsRDSEndpoint, cfg.AwsRDSPort) - return newStoreBase("mysql", connectStr, cfg.AwsDBName) -} diff --git a/sql/rds_test.go b/sql/rds_test.go deleted file mode 100644 index 07c2a734..00000000 --- a/sql/rds_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2019 IoTeX -// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no -// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent -// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache -// License 2.0 that can be found in the LICENSE file. - -package sql - -import ( - "testing" - - "github.com/iotexproject/iotex-core/config" -) - -func TestRDSStorePutGet(t *testing.T) { - t.Skip("Skipping when RDS credentail not provided.") - testRDSStorePutGet := TestStorePutGet - - cfg := config.RDS{} - t.Run("RDS Store", func(t *testing.T) { - testRDSStorePutGet(NewAwsRDS(cfg), t) - }) -} - -func TestRDSStoreTransaction(t *testing.T) { - t.Skip("Skipping when RDS credentail not provided.") - testRDSStoreTransaction := TestStoreTransaction - - cfg := config.RDS{} - t.Run("RDS Store", func(t *testing.T) { - testRDSStoreTransaction(NewAwsRDS(cfg), t) - }) -} diff --git a/sql/storebase.go b/sql/storebase.go index 5bcf0a1d..4186e67c 100644 --- a/sql/storebase.go +++ b/sql/storebase.go @@ -9,6 +9,7 @@ package sql import ( "context" "database/sql" + "errors" "os" "sync" @@ -18,26 +19,54 @@ import ( "github.com/iotexproject/iotex-core/pkg/lifecycle" ) -// Store is the interface of KV store. -type Store interface { - lifecycle.StartStopper +var ( + // ErrNoStoreContext no store in the context + ErrNoStoreContext = errors.New("no store in context") +) + +func WithStore(ctx context.Context, store Store) context.Context { + return context.WithValue(ctx, storeKey{}, store) +} - // Get DB instance - GetDB() *sql.DB +func ExtractStore(ctx context.Context) (Store, bool) { + store, ok := ctx.Value(storeKey{}).(Store) + return store, ok +} - // Transact wrap the transaction - Transact(txFunc func(*sql.Tx) error) (err error) +func WithTx(ctx context.Context, tx *sql.Tx) context.Context { + return context.WithValue(ctx, txKey{}, tx) } -// storebase is a MySQL instance -type storeBase struct { - mutex sync.RWMutex - db *sql.DB - connectStr string - dbName string - driverName string +func ExtractTx(ctx context.Context) (*sql.Tx, bool) { + tx, ok := ctx.Value(txKey{}).(*sql.Tx) + return tx, ok } +type ( + txKey struct{} + storeKey struct{} + + // Store is the interface of KV store. + Store interface { + lifecycle.StartStopper + + // Get DB instance + GetDB() *sql.DB + + // Transact wrap the transaction + Transact(txFunc func(*sql.Tx) error) (err error) + } + + // storebase is a MySQL instance + storeBase struct { + mutex sync.RWMutex + db *sql.DB + connectStr string + dbName string + driverName string + } +) + // logger is initialized with default settings var logger = zerolog.New(os.Stderr).Level(zerolog.InfoLevel).With().Timestamp().Logger()