diff --git a/CHANGELOG.md b/CHANGELOG.md
index 37674d155..ba8e0389b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,33 @@
# Changelog
+## [v0.0.5](https://github.com/CovenantSQL/CovenantSQL/tree/v0.0.5) (2018-11-23)
+
+[Full Changelog](https://github.com/CovenantSQL/CovenantSQL/compare/v0.0.4...v0.0.5)
+
+**Fixed bugs:**
+
+- Stuck in 2pc inconsistent state error [\#56](https://github.com/CovenantSQL/CovenantSQL/issues/56)
+
+**Closed issues:**
+
+- 用 cql 来查看你的钱包余额时出错 [\#111](https://github.com/CovenantSQL/CovenantSQL/issues/111)
+
+**Merged pull requests:**
+
+- Fix table name should add space in one test case. [\#128](https://github.com/CovenantSQL/CovenantSQL/pull/128) ([laodouya](https://github.com/laodouya))
+- Fix memory exhausting issue [\#127](https://github.com/CovenantSQL/CovenantSQL/pull/127) ([leventeliu](https://github.com/leventeliu))
+- Add block cache pruning [\#126](https://github.com/CovenantSQL/CovenantSQL/pull/126) ([leventeliu](https://github.com/leventeliu))
+- Utils/Profiler log field name wrong. [\#124](https://github.com/CovenantSQL/CovenantSQL/pull/124) ([laodouya](https://github.com/laodouya))
+- Add simple Pub Sub framework and fix bug during long march [\#122](https://github.com/CovenantSQL/CovenantSQL/pull/122) ([auxten](https://github.com/auxten))
+- Move client.conn.pCaller init in newConn [\#121](https://github.com/CovenantSQL/CovenantSQL/pull/121) ([auxten](https://github.com/auxten))
+- Fix broken BenchmarkMinerXXX add BenchmarkMinerTwo to travis [\#120](https://github.com/CovenantSQL/CovenantSQL/pull/120) ([auxten](https://github.com/auxten))
+- FUSE on CovenantSQL [\#119](https://github.com/CovenantSQL/CovenantSQL/pull/119) ([auxten](https://github.com/auxten))
+- Integration bench test support on exist database file. [\#118](https://github.com/CovenantSQL/CovenantSQL/pull/118) ([laodouya](https://github.com/laodouya))
+- Move HashSignVerifier definition to crypto package [\#117](https://github.com/CovenantSQL/CovenantSQL/pull/117) ([leventeliu](https://github.com/leventeliu))
+- Increase project test coverage and fix bugs in kayak [\#116](https://github.com/CovenantSQL/CovenantSQL/pull/116) ([xq262144](https://github.com/xq262144))
+- Fix invalid parent, and increate block producing period on main chain [\#115](https://github.com/CovenantSQL/CovenantSQL/pull/115) ([zeqing-guo](https://github.com/zeqing-guo))
+- A shard chain eventual consistency implementation [\#103](https://github.com/CovenantSQL/CovenantSQL/pull/103) ([leventeliu](https://github.com/leventeliu))
+
## [v0.0.4](https://github.com/CovenantSQL/CovenantSQL/tree/v0.0.4) (2018-11-08)
[Full Changelog](https://github.com/CovenantSQL/CovenantSQL/compare/v0.0.3...v0.0.4)
diff --git a/Gopkg.lock b/Gopkg.lock
index dca93369b..f938ce406 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -559,12 +559,12 @@
source = "github.com/CovenantSQL/usql"
[[projects]]
- digest = "1:07aaea55c778d9f0461a429eb19a134f17e9ac3232a5a28b16dfe57c637889bc"
+ branch = "master"
+ digest = "1:fd9ee7072a8121eb2a1592611023924f00492432ef923e561110e4c5e380f285"
name = "github.com/xtaci/smux"
packages = ["."]
pruneopts = "UT"
- revision = "545ecee9d2a96ef4cf3c420c6b4095ac313fe870"
- version = "v1.09"
+ revision = "6cf098d439391c8f8f6a485f8928f47575b6002e"
[[projects]]
digest = "1:4619abe2e9ceabced45ff40a4826866c48f264bb58384efe799a8fb83c2256e0"
diff --git a/Gopkg.toml b/Gopkg.toml
index 89678703c..0b2e9a1b8 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -61,6 +61,10 @@
name = "github.com/CovenantSQL/xurls"
branch = "master"
+[[override]]
+ name = "github.com/xtaci/smux"
+ branch = "master"
+
[[override]]
name = "github.com/siddontang/go-mysql"
source = "github.com/CovenantSQL/go-mysql"
diff --git a/README.md b/README.md
index b54cc285d..ce0125546 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,9 @@
+
+
@@ -77,7 +80,7 @@ that inspired us:
| RPC | `net/rpc` |
| Naming | [**C**onsistent **S**ecure **DHT**](https://godoc.org/github.com/CovenantSQL/CovenantSQL/consistent) |
| Pooling | Session Pool |
-| Multiplex | Yamux |
+| Multiplex | [smux](https://github.com/xtaci/smux) |
| Transport Security | [**E**nhanced **TLS**](https://github.com/CovenantSQL/research/wiki/ETLS(Enhanced-Transport-Layer-Security)) |
| Network | TCP or KCP for optional later |
@@ -112,5 +115,4 @@ Watch us or [](https://gitter.im/CovenantSQL/CovenantSQL?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
diff --git a/client/config.go b/client/config.go
index 9f18a6861..cde8eec94 100644
--- a/client/config.go
+++ b/client/config.go
@@ -18,6 +18,7 @@ package client
import (
"net/url"
+ "strconv"
"strings"
)
@@ -28,11 +29,17 @@ type Config struct {
// additional configs should be filled
// such as read/write/exec timeout
// currently no timeout is supported.
+
+ // UseLeader use leader nodes to do queries
+ UseLeader bool
+
+ // UseFollower use follower nodes to do queries
+ UseFollower bool
}
// NewConfig creates a new config with default value.
func NewConfig() *Config {
- return &Config{}
+ return &Config{UseLeader: true}
}
// FormatDSN formats the given Config into a DSN string which can be passed to the driver.
@@ -45,6 +52,8 @@ func (cfg *Config) FormatDSN() string {
}
newQuery := u.Query()
+ newQuery.Add("use_leader", strconv.FormatBool(cfg.UseLeader))
+ newQuery.Add("use_follower", strconv.FormatBool(cfg.UseFollower))
u.RawQuery = newQuery.Encode()
return u.String()
@@ -58,11 +67,19 @@ func ParseDSN(dsn string) (cfg *Config, err error) {
var u *url.URL
if u, err = url.Parse(dsn); err != nil {
- return
+ return nil, err
}
cfg = NewConfig()
cfg.DatabaseID = u.Host
- return
+ q := u.Query()
+ // option: use_leader, use_follower
+ cfg.UseLeader, _ = strconv.ParseBool(q.Get("use_leader"))
+ cfg.UseFollower, _ = strconv.ParseBool(q.Get("use_follower"))
+ if !cfg.UseLeader && !cfg.UseFollower {
+ cfg.UseLeader = true
+ }
+
+ return cfg, nil
}
diff --git a/client/config_test.go b/client/config_test.go
index f7a3d501b..cbfb7a60d 100644
--- a/client/config_test.go
+++ b/client/config_test.go
@@ -19,28 +19,56 @@ package client
import (
"testing"
- "github.com/CovenantSQL/CovenantSQL/proto"
. "github.com/smartystreets/goconvey/convey"
)
func TestConfig(t *testing.T) {
- Convey("test config", t, func() {
- var cfg *Config
- var err error
+ Convey("test config without additional options", t, func() {
+ cfg, err := ParseDSN("covenantsql://db")
+ So(err, ShouldBeNil)
+ So(cfg, ShouldResemble, &Config{
+ DatabaseID: "db",
+ UseLeader: true,
+ UseFollower: false,
+ })
- cfg, err = ParseDSN("covenantsql://db")
+ recoveredCfg, err := ParseDSN(cfg.FormatDSN())
So(err, ShouldBeNil)
- So(cfg.DatabaseID, ShouldEqual, proto.DatabaseID("db"))
- So(cfg.FormatDSN(), ShouldEqual, "covenantsql://db")
+ So(cfg, ShouldResemble, recoveredCfg)
})
+
Convey("test invalid config", t, func() {
- _, err := ParseDSN("invalid dsn")
+ cfg, err := ParseDSN("invalid dsn")
So(err, ShouldNotBeNil)
+ So(cfg, ShouldBeNil)
})
+
Convey("test dsn with only database id", t, func() {
dbIDStr := "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
cfg, err := ParseDSN(dbIDStr)
So(err, ShouldBeNil)
- So(cfg.DatabaseID, ShouldEqual, dbIDStr)
+ So(cfg, ShouldResemble, &Config{
+ DatabaseID: dbIDStr,
+ UseLeader: true,
+ UseFollower: false,
+ })
+
+ recoveredCfg, err := ParseDSN(cfg.FormatDSN())
+ So(err, ShouldBeNil)
+ So(cfg, ShouldResemble, recoveredCfg)
+ })
+
+ Convey("test dsn with additional options", t, func() {
+ cfg, err := ParseDSN("covenantsql://db?use_leader=0&use_follower=true")
+ So(err, ShouldBeNil)
+ So(cfg, ShouldResemble, &Config{
+ DatabaseID: "db",
+ UseLeader: false,
+ UseFollower: true,
+ })
+
+ recoveredCfg, err := ParseDSN(cfg.FormatDSN())
+ So(err, ShouldBeNil)
+ So(cfg, ShouldResemble, recoveredCfg)
})
}
diff --git a/client/conn.go b/client/conn.go
index eeec4d1db..b0ef613af 100644
--- a/client/conn.go
+++ b/client/conn.go
@@ -31,6 +31,7 @@ import (
"github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/types"
"github.com/CovenantSQL/CovenantSQL/utils/log"
+ "github.com/pkg/errors"
)
// conn implements an interface sql.Conn.
@@ -41,10 +42,18 @@ type conn struct {
localNodeID proto.NodeID
privKey *asymmetric.PrivateKey
- ackCh chan *types.Ack
inTransaction bool
closed int32
- pCaller *rpc.PersistentCaller
+
+ leader *pconn
+ follower *pconn
+}
+
+// pconn represents a connection to a peer
+type pconn struct {
+ parent *conn
+ ackCh chan *types.Ack
+ pCaller *rpc.PersistentCaller
}
func newConn(cfg *Config) (c *conn, err error) {
@@ -67,27 +76,53 @@ func newConn(cfg *Config) (c *conn, err error) {
queries: make([]types.Query, 0),
}
- var peers *proto.Peers
// get peers from BP
+ var peers *proto.Peers
if peers, err = cacheGetPeers(c.dbID, c.privKey); err != nil {
- log.WithError(err).Error("cacheGetPeers failed")
- c = nil
- return
+ return nil, errors.WithMessage(err, "cacheGetPeers failed")
}
- c.pCaller = rpc.NewPersistentCaller(peers.Leader)
- err = c.startAckWorkers(2)
- if err != nil {
- log.WithError(err).Error("startAckWorkers failed")
- c = nil
- return
+ if cfg.UseLeader {
+ c.leader = &pconn{
+ parent: c,
+ pCaller: rpc.NewPersistentCaller(peers.Leader),
+ }
}
- log.WithField("db", c.dbID).Debug("new connection to database")
+ // choose a random follower node
+ if cfg.UseFollower && len(peers.Servers) > 1 {
+ for {
+ node := peers.Servers[randSource.Intn(len(peers.Servers))]
+ if node != peers.Leader {
+ c.follower = &pconn{
+ parent: c,
+ pCaller: rpc.NewPersistentCaller(node),
+ }
+ break
+ }
+ }
+ }
+
+ if c.leader == nil && c.follower == nil {
+ return nil, errors.New("no follower peers found")
+ }
+
+ if c.leader != nil {
+ if err := c.leader.startAckWorkers(2); err != nil {
+ return nil, errors.WithMessage(err, "leader startAckWorkers failed")
+ }
+ }
+ if c.follower != nil {
+ if err := c.follower.startAckWorkers(2); err != nil {
+ return nil, errors.WithMessage(err, "follower startAckWorkers failed")
+ }
+ }
+
+ log.WithField("db", c.dbID).Debug("new connection to database")
return
}
-func (c *conn) startAckWorkers(workerCount int) (err error) {
+func (c *pconn) startAckWorkers(workerCount int) (err error) {
c.ackCh = make(chan *types.Ack, workerCount*4)
for i := 0; i < workerCount; i++ {
go c.ackWorker()
@@ -95,50 +130,52 @@ func (c *conn) startAckWorkers(workerCount int) (err error) {
return
}
-func (c *conn) stopAckWorkers() {
+func (c *pconn) stopAckWorkers() {
close(c.ackCh)
}
-func (c *conn) ackWorker() {
- if rawPeers, ok := peerList.Load(c.dbID); ok {
- if peers, ok := rawPeers.(*proto.Peers); ok {
- var (
- oneTime sync.Once
- pc *rpc.PersistentCaller
- err error
- )
-
- ackWorkerLoop:
- for {
- ack, got := <-c.ackCh
- if !got { //closed and empty
- break ackWorkerLoop
- }
- oneTime.Do(func() {
- pc = rpc.NewPersistentCaller(peers.Leader)
- })
- if err = ack.Sign(c.privKey, false); err != nil {
- log.WithField("target", pc.TargetID).WithError(err).Error("failed to sign ack")
- continue
- }
+func (c *pconn) ackWorker() {
+ var (
+ oneTime sync.Once
+ pc *rpc.PersistentCaller
+ err error
+ )
+
+ackWorkerLoop:
+ for {
+ ack, got := <-c.ackCh
+ if !got { // closed and empty
+ break ackWorkerLoop
+ }
+ oneTime.Do(func() {
+ pc = rpc.NewPersistentCaller(c.pCaller.TargetID)
+ })
+ if err = ack.Sign(c.parent.privKey, false); err != nil {
+ log.WithField("target", pc.TargetID).WithError(err).Error("failed to sign ack")
+ continue
+ }
- var ackRes types.AckResponse
- // send ack back
- if err = pc.Call(route.DBSAck.String(), ack, &ackRes); err != nil {
- log.WithError(err).Warning("send ack failed")
- continue
- }
- }
- if pc != nil {
- pc.CloseStream()
- }
- log.Debug("ack worker quiting")
- return
+ var ackRes types.AckResponse
+ // send ack back
+ if err = pc.Call(route.DBSAck.String(), ack, &ackRes); err != nil {
+ log.WithError(err).Warning("send ack failed")
+ continue
}
}
- log.Fatal("must GetPeers first")
- return
+ if pc != nil {
+ pc.CloseStream()
+ }
+
+ log.Debug("ack worker quiting")
+}
+
+func (c *pconn) close() error {
+ c.stopAckWorkers()
+ if c.pCaller != nil {
+ c.pCaller.CloseStream()
+ }
+ return nil
}
// Prepare implements the driver.Conn.Prepare method.
@@ -152,8 +189,12 @@ func (c *conn) Close() error {
if atomic.CompareAndSwapInt32(&c.closed, 0, 1) {
log.WithField("db", c.dbID).Debug("closed connection")
}
- c.stopAckWorkers()
- c.pCaller.CloseStream()
+ if c.leader != nil {
+ c.leader.close()
+ }
+ if c.follower != nil {
+ c.follower.close()
+ }
return nil
}
@@ -307,9 +348,15 @@ func (c *conn) addQuery(queryType types.QueryType, query *types.Query) (affected
}
func (c *conn) sendQuery(queryType types.QueryType, queries []types.Query) (affectedRows int64, lastInsertID int64, rows driver.Rows, err error) {
- var peers *proto.Peers
- if peers, err = cacheGetPeers(c.dbID, c.privKey); err != nil {
- return
+ var uc *pconn // peer connection used to execute the queries
+
+ uc = c.leader
+ // use follower pconn only when the query is readonly
+ if queryType == types.ReadQuery && c.follower != nil {
+ uc = c.follower
+ }
+ if uc == nil {
+ uc = c.follower
}
// allocate sequence
@@ -322,7 +369,7 @@ func (c *conn) sendQuery(queryType types.QueryType, queries []types.Query) (affe
"type": queryType.String(),
"connID": connID,
"seqNo": seqNo,
- "target": peers.Leader,
+ "target": uc.pCaller.TargetID,
"source": c.localNodeID,
}).WithError(err).Debug("send query")
}()
@@ -349,7 +396,7 @@ func (c *conn) sendQuery(queryType types.QueryType, queries []types.Query) (affe
}
var response types.Response
- if err = c.pCaller.Call(route.DBSQuery.String(), req, &response); err != nil {
+ if err = uc.pCaller.Call(route.DBSQuery.String(), req, &response); err != nil {
return
}
@@ -365,7 +412,7 @@ func (c *conn) sendQuery(queryType types.QueryType, queries []types.Query) (affe
}
// build ack
- c.ackCh <- &types.Ack{
+ uc.ackCh <- &types.Ack{
Header: types.SignedAckHeader{
AckHeader: types.AckHeader{
Response: response.Header,
diff --git a/client/driver_test.go b/client/driver_test.go
index 018cd9665..4fade57e5 100644
--- a/client/driver_test.go
+++ b/client/driver_test.go
@@ -61,7 +61,13 @@ func TestCreate(t *testing.T) {
var dsn string
dsn, err = Create(ResourceMeta{})
So(err, ShouldBeNil)
- So(dsn, ShouldEqual, "covenantsql://db")
+
+ recoveredCfg, err := ParseDSN(dsn)
+ So(err, ShouldBeNil)
+ So(recoveredCfg, ShouldResemble, &Config{
+ DatabaseID: "db",
+ UseLeader: true,
+ })
})
}
diff --git a/cmd/cql-minerd/benchGNTE.sh b/cmd/cql-minerd/benchGNTE.sh
index fd6da72bb..03bd8e2b5 100755
--- a/cmd/cql-minerd/benchGNTE.sh
+++ b/cmd/cql-minerd/benchGNTE.sh
@@ -1,26 +1,26 @@
#!/bin/bash
-../../build.sh && \
-go test -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ && \
-go test -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ && \
-go test -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ && \
-go test -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ && \
-go test -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$
+#../../build.sh && \
+go test -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ |tee gnte.log
+go test -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$ |tee -a gnte.log
-go test -cpu=4 -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ && \
-go test -cpu=4 -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ && \
-go test -cpu=4 -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ && \
-go test -cpu=4 -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ && \
-go test -cpu=4 -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$
+go test -cpu=4 -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=4 -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=4 -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=4 -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=4 -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$ |tee -a gnte.log
-go test -cpu=2 -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ && \
-go test -cpu=2 -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ && \
-go test -cpu=2 -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ && \
-go test -cpu=2 -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ && \
-go test -cpu=2 -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$
+go test -cpu=2 -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=2 -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=2 -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=2 -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=2 -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$ |tee -a gnte.log
-go test -cpu=1 -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ && \
-go test -cpu=1 -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ && \
-go test -cpu=1 -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ && \
-go test -cpu=1 -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ && \
-go test -cpu=1 -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$
+go test -cpu=1 -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=1 -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=1 -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=1 -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ |tee -a gnte.log
+go test -cpu=1 -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$ |tee -a gnte.log
diff --git a/cmd/cql-minerd/integration_test.go b/cmd/cql-minerd/integration_test.go
index bd6237d67..eacb16bce 100644
--- a/cmd/cql-minerd/integration_test.go
+++ b/cmd/cql-minerd/integration_test.go
@@ -35,7 +35,10 @@ import (
"time"
"github.com/CovenantSQL/CovenantSQL/client"
+ "github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
"github.com/CovenantSQL/go-sqlite3-encrypt"
@@ -316,7 +319,7 @@ func stopNodes() {
func TestFullProcess(t *testing.T) {
log.SetLevel(log.DebugLevel)
- Convey("test full process", t, func() {
+ Convey("test full process", t, func(c C) {
startNodes()
defer stopNodes()
var err error
@@ -384,6 +387,68 @@ func TestFullProcess(t *testing.T) {
So(err, ShouldBeNil)
So(resultBytes, ShouldResemble, []byte("ha\001ppy"))
+ Convey("test query cancel", FailureContinues, func(c C) {
+ /* test cancel write query */
+ wg := sync.WaitGroup{}
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ db.Exec("INSERT INTO test VALUES(sleep(10000000000))")
+ }()
+ time.Sleep(time.Second)
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ var err error
+ _, err = db.Exec("UPDATE test SET test = 100;")
+ // should be canceled
+ c.So(err, ShouldNotBeNil)
+ }()
+ time.Sleep(time.Second)
+ for _, n := range conf.GConf.KnownNodes {
+ if n.Role == proto.Miner {
+ rpc.GetSessionPoolInstance().Remove(n.ID)
+ }
+ }
+ time.Sleep(time.Second)
+
+ // ensure connection
+ db.Query("SELECT 1")
+
+ // test before write operation complete
+ var result int
+ err = db.QueryRow("SELECT * FROM test WHERE test = 4 LIMIT 1").Scan(&result)
+ c.So(err, ShouldBeNil)
+ c.So(result, ShouldEqual, 4)
+
+ wg.Wait()
+
+ /* test cancel read query */
+ go func() {
+ _, err = db.Query("SELECT * FROM test WHERE test = sleep(10000000000)")
+ // call write query using read query interface
+ //_, err = db.Query("INSERT INTO test VALUES(sleep(10000000000))")
+ c.So(err, ShouldNotBeNil)
+ }()
+ time.Sleep(time.Second)
+ for _, n := range conf.GConf.KnownNodes {
+ if n.Role == proto.Miner {
+ rpc.GetSessionPoolInstance().Remove(n.ID)
+ }
+ }
+ time.Sleep(time.Second)
+ // ensure connection
+ db.Query("SELECT 1")
+
+ /* test long running write query */
+ row = db.QueryRow("SELECT * FROM test WHERE test = 10000000000 LIMIT 1")
+ err = row.Scan(&result)
+ c.So(err, ShouldBeNil)
+ c.So(result, ShouldEqual, 10000000000)
+
+ c.So(err, ShouldBeNil)
+ })
+
err = db.Close()
So(err, ShouldBeNil)
@@ -427,14 +492,17 @@ func benchDB(b *testing.B, db *sql.DB, createDB bool) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
ii := atomic.AddInt64(&i, 1)
+ index := ROWSTART + ii
+ //start := time.Now()
_, err = db.Exec("INSERT INTO "+TABLENAME+" ( k, v1 ) VALUES"+
- "(?, ?)", ROWSTART+ii, ii,
+ "(?, ?)", index, ii,
)
+ //log.Warnf("Insert index = %d %v", index, time.Since(start))
for err != nil && err.Error() == sqlite3.ErrBusy.Error() {
// retry forever
- log.Warnf("ROWSTART+ii = %d retried", ROWSTART+ii)
+ log.Warnf("index = %d retried", index)
_, err = db.Exec("INSERT INTO "+TABLENAME+" ( k, v1 ) VALUES"+
- "(?, ?)", ROWSTART+ii, ii,
+ "(?, ?)", index, ii,
)
}
if err != nil {
@@ -470,7 +538,9 @@ func benchDB(b *testing.B, db *sql.DB, createDB bool) {
index = rand.Int63n(count - 1)
}
//log.Debugf("index = %d", index)
+ //start := time.Now()
row := db.QueryRow("SELECT v1 FROM "+TABLENAME+" WHERE k = ? LIMIT 1", index)
+ //log.Warnf("Select index = %d %v", index, time.Since(start))
var result []byte
err = row.Scan(&result)
if err != nil || (len(result) == 0) {
diff --git a/cmd/cql-minerd/main.go b/cmd/cql-minerd/main.go
index 1dfbd5b34..ed6c3abb5 100644
--- a/cmd/cql-minerd/main.go
+++ b/cmd/cql-minerd/main.go
@@ -158,7 +158,6 @@ func main() {
// init profile, if cpuProfile, memProfile length is 0, nothing will be done
utils.StartProfile(cpuProfile, memProfile)
- defer utils.StopProfile()
// set generate key pair config
conf.GConf.GenerateKeyPair = genKeyPair
@@ -272,6 +271,7 @@ func main() {
//}
<-signalCh
+ utils.StopProfile()
log.Info("miner stopped")
}
diff --git a/cmd/cql/README.md b/cmd/cql/README.md
index 1b6894726..4d3ec5074 100644
--- a/cmd/cql/README.md
+++ b/cmd/cql/README.md
@@ -30,12 +30,13 @@ INFO[0000] covenant coin balance is: 0 caller="main.go:247 mai
```
Here, I got **"stable coin balance is: 100"**.
-## Initialize a CovenantSQL `cli`
+## Initialize a CovenantSQL `cql`
-After you prepare your master key and config file, CovenantSQL `cli` can be initialized by:
+After you prepare your master key and config file, CovenantSQL `cql` can be initialized by:
You can get a database id when create a new SQL Chain:
```bash
+# if a non-default password applied on master key, use `-password` to pass it
$ cql -config conf/config.yaml -create 1
INFO[0000]
### Public Key ###
diff --git a/kayak/runtime.go b/kayak/runtime.go
index 8c763ceda..1858a803f 100644
--- a/kayak/runtime.go
+++ b/kayak/runtime.go
@@ -35,7 +35,7 @@ import (
const (
// commit channel window size
- commitWindow = 10
+ commitWindow = 0
// prepare window
trackerWindow = 10
)
@@ -246,6 +246,7 @@ func (r *Runtime) Shutdown() (err error) {
// Apply defines entry for Leader node.
func (r *Runtime) Apply(ctx context.Context, req interface{}) (result interface{}, logIndex uint64, err error) {
var commitFuture <-chan *commitResult
+ var cResult *commitResult
var tmStart, tmLeaderPrepare, tmFollowerPrepare, tmCommitEnqueue, tmLeaderRollback,
tmRollback, tmCommitDequeue, tmLeaderCommit, tmCommit time.Time
@@ -350,37 +351,36 @@ func (r *Runtime) Apply(ctx context.Context, req interface{}) (result interface{
tmCommitEnqueue = time.Now()
- select {
- case cResult := <-commitFuture:
- if cResult != nil {
- logIndex = prepareLog.Index
- result = cResult.result
- err = cResult.err
-
- tmCommitDequeue = cResult.start
- dbCost = cResult.dbCost
- tmLeaderCommit = time.Now()
-
- // wait until context deadline or commit done
- if cResult.rpc != nil {
- cResult.rpc.get(ctx)
- }
- } else {
- log.Fatal("IMPOSSIBLE BRANCH")
- select {
- case <-ctx.Done():
- err = errors.Wrap(ctx.Err(), "process commit timeout")
- goto ROLLBACK
- default:
- }
- }
- case <-ctx.Done():
- // pipeline commit timeout
+ if commitFuture == nil {
logIndex = prepareLog.Index
err = errors.Wrap(ctx.Err(), "enqueue commit timeout")
goto ROLLBACK
}
+ cResult = <-commitFuture
+ if cResult != nil {
+ logIndex = prepareLog.Index
+ result = cResult.result
+ err = cResult.err
+
+ tmCommitDequeue = cResult.start
+ dbCost = cResult.dbCost
+ tmLeaderCommit = time.Now()
+
+ // wait until context deadline or commit done
+ if cResult.rpc != nil {
+ cResult.rpc.get(ctx)
+ }
+ } else {
+ log.Fatal("IMPOSSIBLE BRANCH")
+ select {
+ case <-ctx.Done():
+ err = errors.Wrap(ctx.Err(), "process commit timeout")
+ goto ROLLBACK
+ default:
+ }
+ }
+
tmCommit = time.Now()
return
@@ -572,6 +572,7 @@ func (r *Runtime) leaderCommitResult(ctx context.Context, reqPayload interface{}
select {
case <-ctx.Done():
+ res = nil
case r.commitCh <- req:
}
diff --git a/proto/proto.go b/proto/proto.go
index 2f5a812f8..1e04c2999 100644
--- a/proto/proto.go
+++ b/proto/proto.go
@@ -18,6 +18,7 @@
package proto
import (
+ "context"
"time"
)
@@ -30,19 +31,22 @@ type EnvelopeAPI interface {
GetTTL() time.Duration
GetExpire() time.Duration
GetNodeID() *RawNodeID
+ GetContext() context.Context
SetVersion(string)
SetTTL(time.Duration)
SetExpire(time.Duration)
SetNodeID(*RawNodeID)
+ SetContext(context.Context)
}
// Envelope is the protocol header
type Envelope struct {
- Version string `json:"v"`
- TTL time.Duration `json:"t"`
- Expire time.Duration `json:"e"`
- NodeID *RawNodeID `json:"id"`
+ Version string `json:"v"`
+ TTL time.Duration `json:"t"`
+ Expire time.Duration `json:"e"`
+ NodeID *RawNodeID `json:"id"`
+ _ctx context.Context `json:"-"`
}
// PingReq is Ping RPC request
@@ -120,6 +124,14 @@ func (e *Envelope) GetNodeID() *RawNodeID {
return e.NodeID
}
+// GetContext returns context from envelop which is set in server Accept
+func (e *Envelope) GetContext() context.Context {
+ if e._ctx == nil {
+ return context.Background()
+ }
+ return e._ctx
+}
+
// SetVersion implements EnvelopeAPI.SetVersion
func (e *Envelope) SetVersion(ver string) {
e.Version = ver
@@ -140,5 +152,10 @@ func (e *Envelope) SetNodeID(nodeID *RawNodeID) {
e.NodeID = nodeID
}
+// SetContext set a ctx in envelope
+func (e *Envelope) SetContext(ctx context.Context) {
+ e._ctx = ctx
+}
+
// DatabaseID is database name, will be generated from UUID
type DatabaseID string
diff --git a/proto/proto_test.go b/proto/proto_test.go
index 82428d995..50db0d90e 100644
--- a/proto/proto_test.go
+++ b/proto/proto_test.go
@@ -17,6 +17,7 @@
package proto
import (
+ "context"
"testing"
"time"
@@ -41,5 +42,11 @@ func TestEnvelope_GetSet(t *testing.T) {
env.SetVersion("0.0.1")
So(env.GetVersion(), ShouldEqual, "0.0.1")
+
+ ctx := env.GetContext()
+ So(ctx, ShouldEqual, context.Background())
+ cldCtx, _ := context.WithCancel(ctx)
+ env.SetContext(cldCtx)
+ So(env.GetContext(), ShouldEqual, cldCtx)
})
}
diff --git a/rpc/codec.go b/rpc/codec.go
index 63b8f53cc..98f38ce33 100644
--- a/rpc/codec.go
+++ b/rpc/codec.go
@@ -17,6 +17,7 @@
package rpc
import (
+ "context"
"net/rpc"
"github.com/CovenantSQL/CovenantSQL/proto"
@@ -26,13 +27,15 @@ import (
type NodeAwareServerCodec struct {
rpc.ServerCodec
NodeID *proto.RawNodeID
+ Ctx context.Context
}
// NewNodeAwareServerCodec returns new NodeAwareServerCodec with normal rpc.ServerCode and proto.RawNodeID
-func NewNodeAwareServerCodec(codec rpc.ServerCodec, nodeID *proto.RawNodeID) *NodeAwareServerCodec {
+func NewNodeAwareServerCodec(ctx context.Context, codec rpc.ServerCodec, nodeID *proto.RawNodeID) *NodeAwareServerCodec {
return &NodeAwareServerCodec{
ServerCodec: codec,
NodeID: nodeID,
+ Ctx: ctx,
}
}
@@ -51,6 +54,8 @@ func (nc *NodeAwareServerCodec) ReadRequestBody(body interface{}) (err error) {
if r, ok := body.(proto.EnvelopeAPI); ok {
// inject node id to rpc envelope
r.SetNodeID(nc.NodeID)
+ // inject context
+ r.SetContext(nc.Ctx)
}
return
diff --git a/rpc/rpcutil.go b/rpc/rpcutil.go
index d39b12c86..d439dee95 100644
--- a/rpc/rpcutil.go
+++ b/rpc/rpcutil.go
@@ -23,6 +23,7 @@ import (
"math/rand"
"net"
"net/rpc"
+ "strings"
"sync"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
@@ -65,6 +66,7 @@ func (c *PersistentCaller) initClient(isAnonymous bool) (err error) {
c.Lock()
defer c.Unlock()
if c.client == nil {
+ log.Debug("init new rpc client")
var conn net.Conn
conn, err = DialToNode(c.TargetID, c.pool, isAnonymous)
if err != nil {
@@ -93,11 +95,13 @@ func (c *PersistentCaller) Call(method string, args interface{}, reply interface
if err == io.EOF ||
err == io.ErrUnexpectedEOF ||
err == io.ErrClosedPipe ||
- err == rpc.ErrShutdown {
+ err == rpc.ErrShutdown ||
+ strings.Contains(strings.ToLower(err.Error()), "shut down") ||
+ strings.Contains(strings.ToLower(err.Error()), "broken pipe") {
// if got EOF, retry once
- err = c.Reconnect(method)
- if err != nil {
- log.WithField("rpc", method).WithError(err).Error("reconnect failed")
+ reconnectErr := c.ResetClient(method)
+ if reconnectErr != nil {
+ log.WithField("rpc", method).WithError(reconnectErr).Error("reconnect failed")
}
}
log.WithField("rpc", method).WithError(err).Error("call RPC failed")
@@ -105,17 +109,12 @@ func (c *PersistentCaller) Call(method string, args interface{}, reply interface
return
}
-// Reconnect tries to rebuild RPC client
-func (c *PersistentCaller) Reconnect(method string) (err error) {
+// ResetClient resets client.
+func (c *PersistentCaller) ResetClient(method string) (err error) {
c.Lock()
c.Close()
c.client = nil
c.Unlock()
- err = c.initClient(method == route.DHTPing.String())
- if err != nil {
- log.WithField("rpc", method).WithError(err).Error("second init client for RPC failed")
- return
- }
return
}
diff --git a/rpc/server.go b/rpc/server.go
index 159ad76a0..3a56db669 100644
--- a/rpc/server.go
+++ b/rpc/server.go
@@ -17,6 +17,7 @@
package rpc
import (
+ "context"
"io"
"net"
"net/rpc"
@@ -149,7 +150,12 @@ sessionLoop:
}
break sessionLoop
}
- nodeAwareCodec := NewNodeAwareServerCodec(utils.GetMsgPackServerCodec(muxConn), remoteNodeID)
+ ctx, cancelFunc := context.WithCancel(context.Background())
+ go func() {
+ <-muxConn.GetDieCh()
+ cancelFunc()
+ }()
+ nodeAwareCodec := NewNodeAwareServerCodec(ctx, utils.GetMsgPackServerCodec(muxConn), remoteNodeID)
go s.rpcServer.ServeCodec(nodeAwareCodec)
}
}
diff --git a/sqlchain/chain.go b/sqlchain/chain.go
index a95f81c45..326619662 100644
--- a/sqlchain/chain.go
+++ b/sqlchain/chain.go
@@ -18,6 +18,7 @@ package sqlchain
import (
"bytes"
+ "context"
"encoding/binary"
"fmt"
"os"
@@ -112,8 +113,8 @@ type Chain struct {
st *x.State
cl *rpc.Caller
rt *runtime
+ ctx context.Context // ctx is the root context of Chain
- stopCh chan struct{}
blocks chan *types.Block
heights chan int32
responses chan *types.ResponseHeader
@@ -132,8 +133,6 @@ type Chain struct {
observerReplicators map[proto.NodeID]*observerReplicator
// replCh defines the replication trigger channel for replication check.
replCh chan struct{}
- // replWg defines the waitGroups for running replications.
- replWg sync.WaitGroup
// Cached fileds, may need to renew some of this fields later.
//
@@ -143,6 +142,11 @@ type Chain struct {
// NewChain creates a new sql-chain struct.
func NewChain(c *Config) (chain *Chain, err error) {
+ return NewChainWithContext(context.Background(), c)
+}
+
+// NewChainWithContext creates a new sql-chain struct with context.
+func NewChainWithContext(ctx context.Context, c *Config) (chain *Chain, err error) {
// TODO(leventeliu): this is a rough solution, you may also want to clean database file and
// force rebuilding.
var fi os.FileInfo
@@ -202,8 +206,8 @@ func NewChain(c *Config) (chain *Chain, err error) {
ai: newAckIndex(),
st: state,
cl: rpc.NewCaller(),
- rt: newRunTime(c),
- stopCh: make(chan struct{}),
+ rt: newRunTime(ctx, c),
+ ctx: ctx,
blocks: make(chan *types.Block),
heights: make(chan int32, 1),
responses: make(chan *types.ResponseHeader),
@@ -229,6 +233,12 @@ func NewChain(c *Config) (chain *Chain, err error) {
// LoadChain loads the chain state from the specified database and rebuilds a memory index.
func LoadChain(c *Config) (chain *Chain, err error) {
+ return LoadChainWithContext(context.Background(), c)
+}
+
+// LoadChainWithContext loads the chain state from the specified database and rebuilds
+// a memory index with context.
+func LoadChainWithContext(ctx context.Context, c *Config) (chain *Chain, err error) {
// Open LevelDB for block and state
bdbFile := c.ChainFilePrefix + "-block-state.ldb"
bdb, err := leveldb.OpenFile(bdbFile, &leveldbConf)
@@ -272,8 +282,8 @@ func LoadChain(c *Config) (chain *Chain, err error) {
ai: newAckIndex(),
st: xstate,
cl: rpc.NewCaller(),
- rt: newRunTime(c),
- stopCh: make(chan struct{}),
+ rt: newRunTime(ctx, c),
+ ctx: ctx,
blocks: make(chan *types.Block),
heights: make(chan int32, 1),
responses: make(chan *types.ResponseHeader),
@@ -572,7 +582,12 @@ func (c *Chain) produceBlockV2(now time.Time) (err error) {
return
}
// Send to pending list
- c.blocks <- block
+ select {
+ case c.blocks <- block:
+ case <-c.rt.ctx.Done():
+ err = c.rt.ctx.Err()
+ return
+ }
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
@@ -609,28 +624,28 @@ func (c *Chain) produceBlockV2(now time.Time) (err error) {
go func(id proto.NodeID) {
defer wg.Done()
resp := &MuxAdviseNewBlockResp{}
- if err := c.cl.CallNode(
- id, route.SQLCAdviseNewBlock.String(), req, resp); err != nil {
+ if err := c.cl.CallNodeWithContext(
+ c.rt.ctx, id, route.SQLCAdviseNewBlock.String(), req, resp,
+ ); err != nil {
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
"curr_turn": c.rt.getNextTurn(),
"using_timestamp": now.Format(time.RFC3339Nano),
"block_hash": block.BlockHash().String(),
- }).WithError(err).Error(
- "Failed to advise new block")
+ }).WithError(err).Error("Failed to advise new block")
}
}(s)
}
}
wg.Wait()
// fire replication to observers
- c.startStopReplication()
+ c.startStopReplication(c.rt.ctx)
return
}
func (c *Chain) syncHead() {
- // Try to fetch if the the block of the current turn is not advised yet
+ // Try to fetch if the block of the current turn is not advised yet
if h := c.rt.getNextTurn() - 1; c.rt.getHead().Height < h {
var err error
req := &MuxFetchBlockReq{
@@ -662,7 +677,12 @@ func (c *Chain) syncHead() {
"Failed to fetch block from peer")
} else {
statBlock(resp.Block)
- c.blocks <- resp.Block
+ select {
+ case c.blocks <- resp.Block:
+ case <-c.rt.ctx.Done():
+ err = c.rt.ctx.Err()
+ return
+ }
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
@@ -739,16 +759,10 @@ func (c *Chain) runCurrentTurn(now time.Time) {
}
// mainCycle runs main cycle of the sql-chain.
-func (c *Chain) mainCycle() {
- defer func() {
- c.rt.wg.Done()
- // Signal worker goroutines to stop
- close(c.stopCh)
- }()
-
+func (c *Chain) mainCycle(ctx context.Context) {
for {
select {
- case <-c.rt.stopCh:
+ case <-ctx.Done():
return
default:
c.syncHead()
@@ -795,24 +809,26 @@ func (c *Chain) sync() (err error) {
return
}
-func (c *Chain) processBlocks() {
- rsCh := make(chan struct{})
- rsWG := &sync.WaitGroup{}
+func (c *Chain) processBlocks(ctx context.Context) {
+ var (
+ cld, ccl = context.WithCancel(ctx)
+ wg = &sync.WaitGroup{}
+ )
+
returnStash := func(stash []*types.Block) {
- defer rsWG.Done()
+ defer wg.Done()
for _, block := range stash {
select {
case c.blocks <- block:
- case <-rsCh:
+ case <-cld.Done():
return
}
}
}
defer func() {
- close(rsCh)
- rsWG.Wait()
- c.rt.wg.Done()
+ ccl()
+ wg.Wait()
}()
var stash []*types.Block
@@ -825,7 +841,7 @@ func (c *Chain) processBlocks() {
"stashs": len(stash),
}).Debug("Read new height from channel")
if stash != nil {
- rsWG.Add(1)
+ wg.Add(1)
go returnStash(stash)
stash = nil
}
@@ -863,30 +879,8 @@ func (c *Chain) processBlocks() {
}
}
// fire replication to observers
- c.startStopReplication()
- case <-c.stopCh:
- return
- }
- }
-}
-
-func (c *Chain) processResponses() {
- // TODO(leventeliu): implement that
- defer c.rt.wg.Done()
- for {
- select {
- case <-c.stopCh:
- return
- }
- }
-}
-
-func (c *Chain) processAcks() {
- // TODO(leventeliu): implement that
- defer c.rt.wg.Done()
- for {
- select {
- case <-c.stopCh:
+ c.startStopReplication(c.rt.ctx)
+ case <-ctx.Done():
return
}
}
@@ -898,16 +892,9 @@ func (c *Chain) Start() (err error) {
return
}
- c.rt.wg.Add(1)
- go c.processBlocks()
- c.rt.wg.Add(1)
- go c.processResponses()
- c.rt.wg.Add(1)
- go c.processAcks()
- c.rt.wg.Add(1)
- go c.mainCycle()
- c.rt.wg.Add(1)
- go c.replicationCycle()
+ c.rt.goFunc(c.processBlocks)
+ c.rt.goFunc(c.mainCycle)
+ c.rt.goFunc(c.replicationCycle)
c.rt.startService(c)
return
}
@@ -923,7 +910,7 @@ func (c *Chain) Stop() (err error) {
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
- }).Debug("Chain service stopped")
+ }).Debug("Chain service and workers stopped")
// Close LevelDB file
var ierr error
if ierr = c.bdb.Close(); ierr != nil && err == nil {
@@ -1040,7 +1027,7 @@ func (c *Chain) CheckAndPushNewBlock(block *types.Block) (err error) {
// }
// Replicate local state from the new block
- if err = c.st.ReplayBlock(block); err != nil {
+ if err = c.st.ReplayBlockWithContext(c.rt.ctx, block); err != nil {
return
}
@@ -1159,10 +1146,9 @@ func (c *Chain) getBilling(low, high int32) (req *pt.BillingRequest, err error)
return
}
-func (c *Chain) collectBillingSignatures(billings *pt.BillingRequest) {
- defer c.rt.wg.Done()
+func (c *Chain) collectBillingSignatures(ctx context.Context, billings *pt.BillingRequest) {
// Process sign billing responses, note that range iterating over channel will only break if
- // the channle is closed
+ // the channel is closed
req := &MuxSignBillingReq{
Envelope: proto.Envelope{
// TODO(leventeliu): Add fields.
@@ -1212,7 +1198,9 @@ func (c *Chain) collectBillingSignatures(billings *pt.BillingRequest) {
}
var resp interface{}
- if err = c.cl.CallNode(bpNodeID, route.MCCAdviseBillingRequest.String(), bpReq, resp); err != nil {
+ if err = c.cl.CallNodeWithContext(
+ ctx, bpNodeID, route.MCCAdviseBillingRequest.String(), bpReq, resp,
+ ); err != nil {
return
}
}()
@@ -1232,12 +1220,13 @@ func (c *Chain) collectBillingSignatures(billings *pt.BillingRequest) {
defer rpcWG.Done()
resp := &MuxSignBillingResp{}
- if err := c.cl.CallNode(id, route.SQLCSignBilling.String(), req, resp); err != nil {
+ if err := c.cl.CallNodeWithContext(
+ ctx, id, route.SQLCSignBilling.String(), req, resp,
+ ); err != nil {
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
- }).WithError(err).Error(
- "Failed to send sign billing request")
+ }).WithError(err).Error("Failed to send sign billing request")
}
respC <- &resp.SignBillingResp
@@ -1268,8 +1257,7 @@ func (c *Chain) LaunchBilling(low, high int32) (err error) {
return
}
- c.rt.wg.Add(1)
- go c.collectBillingSignatures(req)
+ c.rt.goFunc(func(ctx context.Context) { c.collectBillingSignatures(ctx, req) })
return
}
@@ -1307,7 +1295,7 @@ func (c *Chain) addSubscription(nodeID proto.NodeID, startHeight int32) (err err
c.observerLock.Lock()
defer c.observerLock.Unlock()
c.observers[nodeID] = startHeight
- c.startStopReplication()
+ c.startStopReplication(c.rt.ctx)
return
}
@@ -1316,15 +1304,15 @@ func (c *Chain) cancelSubscription(nodeID proto.NodeID) (err error) {
c.observerLock.Lock()
defer c.observerLock.Unlock()
delete(c.observers, nodeID)
- c.startStopReplication()
+ c.startStopReplication(c.rt.ctx)
return
}
-func (c *Chain) startStopReplication() {
+func (c *Chain) startStopReplication(ctx context.Context) {
if c.replCh != nil {
select {
case c.replCh <- struct{}{}:
- case <-c.stopCh:
+ case <-ctx.Done():
default:
}
}
@@ -1344,10 +1332,9 @@ func (c *Chain) populateObservers() {
}
} else {
// start new replication routine
- c.replWg.Add(1)
replicator := newObserverReplicator(nodeID, startHeight, c)
c.observerReplicators[nodeID] = replicator
- go replicator.run()
+ c.rt.goFunc(replicator.run)
}
}
@@ -1360,12 +1347,7 @@ func (c *Chain) populateObservers() {
}
}
-func (c *Chain) replicationCycle() {
- defer func() {
- c.replWg.Wait()
- c.rt.wg.Done()
- }()
-
+func (c *Chain) replicationCycle(ctx context.Context) {
for {
select {
case <-c.replCh:
@@ -1375,7 +1357,7 @@ func (c *Chain) replicationCycle() {
for _, replicator := range c.observerReplicators {
replicator.tick()
}
- case <-c.stopCh:
+ case <-ctx.Done():
return
}
}
@@ -1384,7 +1366,9 @@ func (c *Chain) replicationCycle() {
// Query queries req from local chain state and returns the query results in resp.
func (c *Chain) Query(req *types.Request) (resp *types.Response, err error) {
var ref *x.QueryTracker
- if ref, resp, err = c.st.Query(req); err != nil {
+ // TODO(leventeliu): we're using an external context passed by request. Make sure that
+ // cancelling will be propagated to this context before chain instance stops.
+ if ref, resp, err = c.st.QueryWithContext(req.GetContext(), req); err != nil {
return
}
if err = resp.Sign(c.pk); err != nil {
@@ -1403,7 +1387,7 @@ func (c *Chain) Replay(req *types.Request, resp *types.Response) (err error) {
case types.ReadQuery:
return
case types.WriteQuery:
- return c.st.Replay(req, resp)
+ return c.st.ReplayWithContext(req.GetContext(), req, resp)
default:
err = ErrInvalidRequest
}
diff --git a/sqlchain/observer.go b/sqlchain/observer.go
index e1fa19960..5e293578c 100644
--- a/sqlchain/observer.go
+++ b/sqlchain/observer.go
@@ -17,6 +17,7 @@
package sqlchain
import (
+ "context"
"sync"
"github.com/CovenantSQL/CovenantSQL/proto"
@@ -59,7 +60,6 @@ func newObserverReplicator(nodeID proto.NodeID, startHeight int32, c *Chain) *ob
func (r *observerReplicator) setNewHeight(newHeight int32) {
r.replLock.Lock()
defer r.replLock.Unlock()
-
r.height = newHeight
}
@@ -241,15 +241,13 @@ func (r *observerReplicator) tick() {
default:
}
}
-func (r *observerReplicator) run() {
- defer r.c.replWg.Done()
-
+func (r *observerReplicator) run(ctx context.Context) {
for {
select {
case <-r.triggerCh:
// replication
r.replicate()
- case <-r.c.stopCh:
+ case <-ctx.Done():
r.stop()
return
case <-r.stopCh:
diff --git a/sqlchain/runtime.go b/sqlchain/runtime.go
index b1935558d..14cdabf32 100644
--- a/sqlchain/runtime.go
+++ b/sqlchain/runtime.go
@@ -17,6 +17,7 @@
package sqlchain
import (
+ "context"
"fmt"
"sync"
"time"
@@ -29,8 +30,9 @@ import (
// runtime represents a chain runtime state.
type runtime struct {
- wg sync.WaitGroup
- stopCh chan struct{}
+ wg *sync.WaitGroup
+ ctx context.Context
+ cancel context.CancelFunc
// chainInitTime is the initial cycle time, when the Genesis blcok is produced.
chainInitTime time.Time
@@ -85,9 +87,13 @@ type runtime struct {
}
// newRunTime returns a new sql-chain runtime instance with the specified config.
-func newRunTime(c *Config) (r *runtime) {
+func newRunTime(ctx context.Context, c *Config) (r *runtime) {
+ var cld, ccl = context.WithCancel(ctx)
r = &runtime{
- stopCh: make(chan struct{}),
+ wg: &sync.WaitGroup{},
+ ctx: cld,
+ cancel: ccl,
+
databaseID: c.DatabaseID,
period: c.Period,
tick: c.Tick,
@@ -204,11 +210,7 @@ func (r *runtime) getQueryGas(t types.QueryType) uint64 {
// stop sends a signal to the Runtime stop channel by closing it.
func (r *runtime) stop() {
r.stopService()
- select {
- case <-r.stopCh:
- default:
- close(r.stopCh)
- }
+ r.cancel()
r.wg.Wait()
}
@@ -328,3 +330,11 @@ func (r *runtime) setHead(head *state) {
defer r.stateMutex.Unlock()
r.head = head
}
+
+func (r *runtime) goFunc(f func(context.Context)) {
+ r.wg.Add(1)
+ go func() {
+ defer r.wg.Done()
+ f(r.ctx)
+ }()
+}
diff --git a/test/GNTE/GNTE b/test/GNTE/GNTE
index 93e48d707..d34ad0da6 160000
--- a/test/GNTE/GNTE
+++ b/test/GNTE/GNTE
@@ -1 +1 @@
-Subproject commit 93e48d7072b002c3d070f9b712ff22b53c65c6b3
+Subproject commit d34ad0da6cf6fb07065da2fb8e050366adb58123
diff --git a/test/GNTE/conf/gnte.yaml b/test/GNTE/conf/gnte.yaml
index 11c5eebb6..0ffb819b8 100644
--- a/test/GNTE/conf/gnte.yaml
+++ b/test/GNTE/conf/gnte.yaml
@@ -12,8 +12,7 @@ group:
- # bp10.250.1.4
ip: 10.250.1.4/32
cmd: "cd /scripts && ./bin/cqld -config ./node_2/config.yaml"
- delay: "100ms 1ms 1%"
- rate: "100mbit"
+ rate: "1000mbit"
-
name: miner
nodes:
@@ -41,8 +40,7 @@ group:
- # miner10.250.100.9
ip: 10.250.100.9/32
cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.9/config.yaml"
- delay: "100ms 1ms 1%"
- rate: "100mbit"
+ rate: "1000mbit"
-
name: client
nodes:
@@ -52,28 +50,24 @@ group:
- # node_adapter
ip: 10.250.0.254/32
cmd: "cd /scripts && ./bin/cql-adapter -config ./node_c/config.yaml"
- delay: "100ms 1ms 1%"
- rate: "100mbit"
+ rate: "1000mbit"
network:
-
groups:
- bp
- miner
- delay: "100ms 1ms 1%"
- rate: "10mbit"
+ rate: "1000mbit"
-
groups:
- bp
- client
- delay: "100ms 1ms 1%"
- rate: "10mbit"
+ rate: "1000mbit"
-
groups:
- client
- miner
- delay: "100ms 1ms 1%"
- rate: "10mbit"
+ rate: "1000mbit"
diff --git a/test/GNTE/conf/gnte_0ms.yaml b/test/GNTE/conf/gnte_0ms.yaml
new file mode 100644
index 000000000..0ffb819b8
--- /dev/null
+++ b/test/GNTE/conf/gnte_0ms.yaml
@@ -0,0 +1,73 @@
+# Only support 10.250.0.2 ~ 10.250.254.254
+group:
+ -
+ name: bp
+ nodes:
+ - # bp10.250.1.2
+ ip: 10.250.1.2/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_0/config.yaml"
+ - # bp10.250.1.3
+ ip: 10.250.1.3/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_1/config.yaml"
+ - # bp10.250.1.4
+ ip: 10.250.1.4/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_2/config.yaml"
+ rate: "1000mbit"
+ -
+ name: miner
+ nodes:
+ - # miner10.250.100.2
+ ip: 10.250.100.2/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.2/config.yaml"
+ - # miner10.250.100.3
+ ip: 10.250.100.3/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.3/config.yaml"
+ - # miner10.250.100.4
+ ip: 10.250.100.4/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.4/config.yaml"
+ - # miner10.250.100.5
+ ip: 10.250.100.5/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.5/config.yaml"
+ - # miner10.250.100.6
+ ip: 10.250.100.6/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.6/config.yaml"
+ - # miner10.250.100.7
+ ip: 10.250.100.7/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.7/config.yaml"
+ - # miner10.250.100.8
+ ip: 10.250.100.8/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.8/config.yaml"
+ - # miner10.250.100.9
+ ip: 10.250.100.9/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.9/config.yaml"
+ rate: "1000mbit"
+ -
+ name: client
+ nodes:
+ - # node_c
+ ip: 10.250.0.2/32
+ cmd: "ping -c3 g.cn"
+ - # node_adapter
+ ip: 10.250.0.254/32
+ cmd: "cd /scripts && ./bin/cql-adapter -config ./node_c/config.yaml"
+ rate: "1000mbit"
+
+network:
+ -
+ groups:
+ - bp
+ - miner
+ rate: "1000mbit"
+
+ -
+ groups:
+ - bp
+ - client
+ rate: "1000mbit"
+
+ -
+ groups:
+ - client
+ - miner
+ rate: "1000mbit"
+
diff --git a/test/GNTE/conf/gnte_100ms.yaml b/test/GNTE/conf/gnte_100ms.yaml
new file mode 100644
index 000000000..5cb7d815f
--- /dev/null
+++ b/test/GNTE/conf/gnte_100ms.yaml
@@ -0,0 +1,79 @@
+# Only support 10.250.0.2 ~ 10.250.254.254
+group:
+ -
+ name: bp
+ nodes:
+ - # bp10.250.1.2
+ ip: 10.250.1.2/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_0/config.yaml"
+ - # bp10.250.1.3
+ ip: 10.250.1.3/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_1/config.yaml"
+ - # bp10.250.1.4
+ ip: 10.250.1.4/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_2/config.yaml"
+ delay: "100ms"
+ rate: "1000mbit"
+ -
+ name: miner
+ nodes:
+ - # miner10.250.100.2
+ ip: 10.250.100.2/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.2/config.yaml"
+ - # miner10.250.100.3
+ ip: 10.250.100.3/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.3/config.yaml"
+ - # miner10.250.100.4
+ ip: 10.250.100.4/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.4/config.yaml"
+ - # miner10.250.100.5
+ ip: 10.250.100.5/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.5/config.yaml"
+ - # miner10.250.100.6
+ ip: 10.250.100.6/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.6/config.yaml"
+ - # miner10.250.100.7
+ ip: 10.250.100.7/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.7/config.yaml"
+ - # miner10.250.100.8
+ ip: 10.250.100.8/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.8/config.yaml"
+ - # miner10.250.100.9
+ ip: 10.250.100.9/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.9/config.yaml"
+ delay: "100ms"
+ rate: "1000mbit"
+ -
+ name: client
+ nodes:
+ - # node_c
+ ip: 10.250.0.2/32
+ cmd: "ping -c3 g.cn"
+ - # node_adapter
+ ip: 10.250.0.254/32
+ cmd: "cd /scripts && ./bin/cql-adapter -config ./node_c/config.yaml"
+ delay: "100ms"
+ rate: "1000mbit"
+
+network:
+ -
+ groups:
+ - bp
+ - miner
+ delay: "100ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - bp
+ - client
+ delay: "100ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - client
+ - miner
+ delay: "100ms"
+ rate: "1000mbit"
+
diff --git a/test/GNTE/conf/gnte_200ms.yaml b/test/GNTE/conf/gnte_200ms.yaml
new file mode 100644
index 000000000..6a75a4f06
--- /dev/null
+++ b/test/GNTE/conf/gnte_200ms.yaml
@@ -0,0 +1,79 @@
+# Only support 10.250.0.2 ~ 10.250.254.254
+group:
+ -
+ name: bp
+ nodes:
+ - # bp10.250.1.2
+ ip: 10.250.1.2/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_0/config.yaml"
+ - # bp10.250.1.3
+ ip: 10.250.1.3/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_1/config.yaml"
+ - # bp10.250.1.4
+ ip: 10.250.1.4/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_2/config.yaml"
+ delay: "200ms"
+ rate: "1000mbit"
+ -
+ name: miner
+ nodes:
+ - # miner10.250.100.2
+ ip: 10.250.100.2/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.2/config.yaml"
+ - # miner10.250.100.3
+ ip: 10.250.100.3/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.3/config.yaml"
+ - # miner10.250.100.4
+ ip: 10.250.100.4/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.4/config.yaml"
+ - # miner10.250.100.5
+ ip: 10.250.100.5/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.5/config.yaml"
+ - # miner10.250.100.6
+ ip: 10.250.100.6/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.6/config.yaml"
+ - # miner10.250.100.7
+ ip: 10.250.100.7/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.7/config.yaml"
+ - # miner10.250.100.8
+ ip: 10.250.100.8/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.8/config.yaml"
+ - # miner10.250.100.9
+ ip: 10.250.100.9/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.9/config.yaml"
+ delay: "200ms"
+ rate: "1000mbit"
+ -
+ name: client
+ nodes:
+ - # node_c
+ ip: 10.250.0.2/32
+ cmd: "ping -c3 g.cn"
+ - # node_adapter
+ ip: 10.250.0.254/32
+ cmd: "cd /scripts && ./bin/cql-adapter -config ./node_c/config.yaml"
+ delay: "200ms"
+ rate: "1000mbit"
+
+network:
+ -
+ groups:
+ - bp
+ - miner
+ delay: "200ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - bp
+ - client
+ delay: "200ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - client
+ - miner
+ delay: "200ms"
+ rate: "1000mbit"
+
diff --git a/test/GNTE/conf/gnte_20ms.yaml b/test/GNTE/conf/gnte_20ms.yaml
new file mode 100644
index 000000000..c1e648e1c
--- /dev/null
+++ b/test/GNTE/conf/gnte_20ms.yaml
@@ -0,0 +1,79 @@
+# Only support 10.250.0.2 ~ 10.250.254.254
+group:
+ -
+ name: bp
+ nodes:
+ - # bp10.250.1.2
+ ip: 10.250.1.2/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_0/config.yaml"
+ - # bp10.250.1.3
+ ip: 10.250.1.3/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_1/config.yaml"
+ - # bp10.250.1.4
+ ip: 10.250.1.4/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_2/config.yaml"
+ delay: "20ms"
+ rate: "1000mbit"
+ -
+ name: miner
+ nodes:
+ - # miner10.250.100.2
+ ip: 10.250.100.2/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.2/config.yaml"
+ - # miner10.250.100.3
+ ip: 10.250.100.3/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.3/config.yaml"
+ - # miner10.250.100.4
+ ip: 10.250.100.4/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.4/config.yaml"
+ - # miner10.250.100.5
+ ip: 10.250.100.5/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.5/config.yaml"
+ - # miner10.250.100.6
+ ip: 10.250.100.6/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.6/config.yaml"
+ - # miner10.250.100.7
+ ip: 10.250.100.7/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.7/config.yaml"
+ - # miner10.250.100.8
+ ip: 10.250.100.8/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.8/config.yaml"
+ - # miner10.250.100.9
+ ip: 10.250.100.9/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.9/config.yaml"
+ delay: "20ms"
+ rate: "1000mbit"
+ -
+ name: client
+ nodes:
+ - # node_c
+ ip: 10.250.0.2/32
+ cmd: "ping -c3 g.cn"
+ - # node_adapter
+ ip: 10.250.0.254/32
+ cmd: "cd /scripts && ./bin/cql-adapter -config ./node_c/config.yaml"
+ delay: "20ms"
+ rate: "1000mbit"
+
+network:
+ -
+ groups:
+ - bp
+ - miner
+ delay: "20ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - bp
+ - client
+ delay: "20ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - client
+ - miner
+ delay: "20ms"
+ rate: "1000mbit"
+
diff --git a/test/GNTE/conf/gnte_5ms.yaml b/test/GNTE/conf/gnte_5ms.yaml
new file mode 100644
index 000000000..86392bd32
--- /dev/null
+++ b/test/GNTE/conf/gnte_5ms.yaml
@@ -0,0 +1,79 @@
+# Only support 10.250.0.2 ~ 10.250.254.254
+group:
+ -
+ name: bp
+ nodes:
+ - # bp10.250.1.2
+ ip: 10.250.1.2/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_0/config.yaml"
+ - # bp10.250.1.3
+ ip: 10.250.1.3/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_1/config.yaml"
+ - # bp10.250.1.4
+ ip: 10.250.1.4/32
+ cmd: "cd /scripts && ./bin/cqld -config ./node_2/config.yaml"
+ delay: "5ms"
+ rate: "1000mbit"
+ -
+ name: miner
+ nodes:
+ - # miner10.250.100.2
+ ip: 10.250.100.2/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.2/config.yaml"
+ - # miner10.250.100.3
+ ip: 10.250.100.3/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.3/config.yaml"
+ - # miner10.250.100.4
+ ip: 10.250.100.4/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.4/config.yaml"
+ - # miner10.250.100.5
+ ip: 10.250.100.5/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.5/config.yaml"
+ - # miner10.250.100.6
+ ip: 10.250.100.6/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.6/config.yaml"
+ - # miner10.250.100.7
+ ip: 10.250.100.7/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.7/config.yaml"
+ - # miner10.250.100.8
+ ip: 10.250.100.8/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.8/config.yaml"
+ - # miner10.250.100.9
+ ip: 10.250.100.9/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.9/config.yaml"
+ delay: "5ms"
+ rate: "1000mbit"
+ -
+ name: client
+ nodes:
+ - # node_c
+ ip: 10.250.0.2/32
+ cmd: "ping -c3 g.cn"
+ - # node_adapter
+ ip: 10.250.0.254/32
+ cmd: "cd /scripts && ./bin/cql-adapter -config ./node_c/config.yaml"
+ delay: "5ms"
+ rate: "1000mbit"
+
+network:
+ -
+ groups:
+ - bp
+ - miner
+ delay: "5ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - bp
+ - client
+ delay: "5ms"
+ rate: "1000mbit"
+
+ -
+ groups:
+ - client
+ - miner
+ delay: "5ms"
+ rate: "1000mbit"
+
diff --git a/test/GNTE/conf/node_0/config.yaml b/test/GNTE/conf/node_0/config.yaml
index d0f183e52..5999a7e55 100644
--- a/test/GNTE/conf/node_0/config.yaml
+++ b/test/GNTE/conf/node_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/GNTE/conf/node_1/config.yaml b/test/GNTE/conf/node_1/config.yaml
index 70f6ca0f8..15df963f9 100644
--- a/test/GNTE/conf/node_1/config.yaml
+++ b/test/GNTE/conf/node_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/GNTE/conf/node_2/config.yaml b/test/GNTE/conf/node_2/config.yaml
index c1321a15c..5cbac829d 100644
--- a/test/GNTE/conf/node_2/config.yaml
+++ b/test/GNTE/conf/node_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/GNTE/conf/node_c/config.yaml b/test/GNTE/conf/node_c/config.yaml
index 75aa1975c..242705fbb 100644
--- a/test/GNTE/conf/node_c/config.yaml
+++ b/test/GNTE/conf/node_c/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/GNTE/conf/node_miner_10.250.100.2/config.yaml b/test/GNTE/conf/node_miner_10.250.100.2/config.yaml
index 2a301d150..11f86f067 100644
--- a/test/GNTE/conf/node_miner_10.250.100.2/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/conf/node_miner_10.250.100.3/config.yaml b/test/GNTE/conf/node_miner_10.250.100.3/config.yaml
index 1106c28bb..af4ebc1fd 100644
--- a/test/GNTE/conf/node_miner_10.250.100.3/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.3/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/conf/node_miner_10.250.100.4/config.yaml b/test/GNTE/conf/node_miner_10.250.100.4/config.yaml
index b19dace89..451175275 100644
--- a/test/GNTE/conf/node_miner_10.250.100.4/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.4/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/conf/node_miner_10.250.100.5/config.yaml b/test/GNTE/conf/node_miner_10.250.100.5/config.yaml
index a09d83606..c89c325cf 100755
--- a/test/GNTE/conf/node_miner_10.250.100.5/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.5/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/conf/node_miner_10.250.100.6/config.yaml b/test/GNTE/conf/node_miner_10.250.100.6/config.yaml
index b96505d19..7e20eae29 100755
--- a/test/GNTE/conf/node_miner_10.250.100.6/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.6/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/conf/node_miner_10.250.100.7/config.yaml b/test/GNTE/conf/node_miner_10.250.100.7/config.yaml
index 5370e24f6..e88979235 100755
--- a/test/GNTE/conf/node_miner_10.250.100.7/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.7/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/conf/node_miner_10.250.100.8/config.yaml b/test/GNTE/conf/node_miner_10.250.100.8/config.yaml
index bc633a6fc..94c0a66dd 100755
--- a/test/GNTE/conf/node_miner_10.250.100.8/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.8/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/conf/node_miner_10.250.100.9/config.yaml b/test/GNTE/conf/node_miner_10.250.100.9/config.yaml
index 887064529..b233b95c4 100755
--- a/test/GNTE/conf/node_miner_10.250.100.9/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.9/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/GNTE/run.sh b/test/GNTE/run.sh
index 44fc9624c..69ca7800a 100755
--- a/test/GNTE/run.sh
+++ b/test/GNTE/run.sh
@@ -1,38 +1,65 @@
#!/bin/bash -x
+yaml[0]=./scripts/gnte_0ms.yaml
+yaml[1]=./scripts/gnte_5ms.yaml
+yaml[2]=./scripts/gnte_20ms.yaml
+yaml[3]=./scripts/gnte_100ms.yaml
+yaml[4]=./scripts/gnte_200ms.yaml
+
TEST_WD=$(cd $(dirname $0)/; pwd)
PROJECT_DIR=$(cd ${TEST_WD}/../../; pwd)
echo ${PROJECT_DIR}
-cd ${PROJECT_DIR} && ./build.sh
+# Build
+#Notice!!!!: uncomment this when you run this manually.
+#cd ${PROJECT_DIR} && ./build.sh
-if [ -d ${TEST_WD}/GNTE/scripts/bin ];then
- mv ${TEST_WD}/GNTE/scripts/bin{,.bak}
+BENCHRESULT_FILE=${PROJECT_DIR}/bench.txt
+if [ -f ${BENCHRESULT_FILE} ];then
+ rm -rf ${BENCHRESULT_FILE}
+fi
+tmp_file=${PROJECT_DIR}/tmp.log
+if [ -f ${tmp_file} ];then
+ rm -rf ${tmp_file}
fi
-cd ${PROJECT_DIR} && cp ./cleanupDB.sh ${TEST_WD}/GNTE/scripts
+# Clean submodule
+cd ${TEST_WD}/GNTE/ && git clean -dfx
+
+for gnte_yaml in ${yaml[@]};
+do
+ if [ -d ${TEST_WD}/GNTE/scripts/bin ];then
+ rm -rf ${TEST_WD}/GNTE/scripts/bin
+ fi
+
+ # Prepare
+ cd ${PROJECT_DIR} && cp ./cleanupDB.sh ${TEST_WD}/GNTE/scripts
+ cd ${PROJECT_DIR} && cp -r ./bin ${TEST_WD}/GNTE/scripts
+ cd ${TEST_WD} && cp -r ./conf/* ./GNTE/scripts
+ cd ${TEST_WD}/GNTE && bash -x ./build.sh
+
+ # Clean
+ cd ${TEST_WD} && bash ./GNTE/scripts/cleanupDB.sh
+ cd ${TEST_WD}/GNTE && bash -x ./generate.sh ${gnte_yaml}
+
+ # Bench GNTE
+ cd ${PROJECT_DIR}/cmd/cql-minerd/
+ bash -x ./benchGNTE.sh
+ echo "${gnte_yaml}" >> ${tmp_file}
+ grep BenchmarkMinerGNTE gnte.log >> ${tmp_file}
+ echo "" >> ${tmp_file}
+done
+
+# clean GNTE docker
cd ${TEST_WD} && bash ./GNTE/scripts/cleanupDB.sh
-cd ${PROJECT_DIR} && cp -r ./bin ${TEST_WD}/GNTE/scripts
-
-cd ${TEST_WD} && cp -r ./conf/* ./GNTE/scripts
-
-cd ${TEST_WD}/GNTE && bash -x ./build.sh
-cd ${TEST_WD}/GNTE && bash -x ./generate.sh ./scripts/gnte.yaml
-rm -rf ${TEST_WD}/GNTE/scripts/bin.bak
-
-#BUILD_IMG="covenantsql/build"
-#BENCH_CONTAIN="bench10.250.1.8"
-#INSIDE_GOPATH=$(docker run -it --rm ${BUILD_IMG} bash -c 'echo -n "$GOPATH"')
-#docker run -itd \
-# --name ${BENCH_CONTAIN}\
-# --net container:client10.250.1.8 \
-# -v ${PROJECT_DIR}/../:${INSIDE_GOPATH}/src/github.com/CovenantSQL/ \
-# ${BUILD_IMG} tail -f /dev/null
-#
-#docker exec -it ${BENCH_CONTAIN} bash -c \
-# "cd ${INSIDE_GOPATH}/src/github.com/CovenantSQL/CovenantSQL/client && go test -bench . -run BenchmarkCovenantSQLDriver"
-#
-#docker rm -f ${BENCH_CONTAIN}
+cd ${TEST_WD} && bash ./GNTE/scripts/clean.sh
+
+perl -lane 'print $F[0], "\t", $F[1], "\t", $F[2], "\t", 1000000000.0/$F[2] if $F[2]; print if /script/' ${tmp_file} > ${BENCHRESULT_FILE}
+#cd ${TEST_WD}/GNTE && bash -x ./generate.sh stopall miner
+#cd test/GNTE/GNTE/scripts/node_miner_10.250.100.3/
+#cd data/randomid
+#replace storage.db3* file
+#cd ${TEST_WD}/GNTE && bash -x ./generate.sh startall
diff --git a/test/bootstrap.yaml b/test/bootstrap.yaml
index 08c2c7c50..7b4ba2b29 100644
--- a/test/bootstrap.yaml
+++ b/test/bootstrap.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: true
diff --git a/test/fuse/node_0/config.yaml b/test/fuse/node_0/config.yaml
index 9919e977e..b190fe355 100644
--- a/test/fuse/node_0/config.yaml
+++ b/test/fuse/node_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/fuse/node_1/config.yaml b/test/fuse/node_1/config.yaml
index caaa118d5..504bf58e2 100644
--- a/test/fuse/node_1/config.yaml
+++ b/test/fuse/node_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/fuse/node_2/config.yaml b/test/fuse/node_2/config.yaml
index 18c3409d0..3cca205f2 100644
--- a/test/fuse/node_2/config.yaml
+++ b/test/fuse/node_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/fuse/node_c/config.yaml b/test/fuse/node_c/config.yaml
index d90eca3fe..b01fdbbf4 100644
--- a/test/fuse/node_c/config.yaml
+++ b/test/fuse/node_c/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/fuse/node_miner_0/config.yaml b/test/fuse/node_miner_0/config.yaml
index 448bb795f..93253c1e1 100644
--- a/test/fuse/node_miner_0/config.yaml
+++ b/test/fuse/node_miner_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/fuse/node_miner_1/config.yaml b/test/fuse/node_miner_1/config.yaml
index 558ca1cb1..54b02f8bc 100644
--- a/test/fuse/node_miner_1/config.yaml
+++ b/test/fuse/node_miner_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/fuse/node_miner_2/config.yaml b/test/fuse/node_miner_2/config.yaml
index e6edd4d68..8ca540e29 100644
--- a/test/fuse/node_miner_2/config.yaml
+++ b/test/fuse/node_miner_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/integration/node_0/config.yaml b/test/integration/node_0/config.yaml
index af162afb2..9548dfbf1 100644
--- a/test/integration/node_0/config.yaml
+++ b/test/integration/node_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/integration/node_1/config.yaml b/test/integration/node_1/config.yaml
index 0aa1f5a9b..ed74ff6c3 100644
--- a/test/integration/node_1/config.yaml
+++ b/test/integration/node_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/integration/node_2/config.yaml b/test/integration/node_2/config.yaml
index 8f36e3ab9..fa4f7dc68 100644
--- a/test/integration/node_2/config.yaml
+++ b/test/integration/node_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/integration/node_c/config.yaml b/test/integration/node_c/config.yaml
index fe9fa6eb2..f710dc823 100644
--- a/test/integration/node_c/config.yaml
+++ b/test/integration/node_c/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/integration/node_miner_0/config.yaml b/test/integration/node_miner_0/config.yaml
index 8fd498a09..caf22c309 100644
--- a/test/integration/node_miner_0/config.yaml
+++ b/test/integration/node_miner_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/integration/node_miner_1/config.yaml b/test/integration/node_miner_1/config.yaml
index a2b44aaf6..b375805c4 100644
--- a/test/integration/node_miner_1/config.yaml
+++ b/test/integration/node_miner_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/integration/node_miner_2/config.yaml b/test/integration/node_miner_2/config.yaml
index 900670988..8d8ed7429 100644
--- a/test/integration/node_miner_2/config.yaml
+++ b/test/integration/node_miner_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/leak/client.yaml b/test/leak/client.yaml
index 89911d9ef..d31330f6e 100644
--- a/test/leak/client.yaml
+++ b/test/leak/client.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/leak/leader.yaml b/test/leak/leader.yaml
index 330ee46b5..db3098e14 100644
--- a/test/leak/leader.yaml
+++ b/test/leak/leader.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_0/config.yaml b/test/mainchain/node_0/config.yaml
index 866534570..b212ca348 100644
--- a/test/mainchain/node_0/config.yaml
+++ b/test/mainchain/node_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_1/config.yaml b/test/mainchain/node_1/config.yaml
index c53b9fba4..455bf210b 100644
--- a/test/mainchain/node_1/config.yaml
+++ b/test/mainchain/node_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_2/config.yaml b/test/mainchain/node_2/config.yaml
index b15a972b7..f00b915d4 100644
--- a/test/mainchain/node_2/config.yaml
+++ b/test/mainchain/node_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_c/config.yaml b/test/mainchain/node_c/config.yaml
index 9c509ef03..9cf42891b 100644
--- a/test/mainchain/node_c/config.yaml
+++ b/test/mainchain/node_c/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_miner_0/config.yaml b/test/mainchain/node_miner_0/config.yaml
index b5f65dc73..b7a496d61 100644
--- a/test/mainchain/node_miner_0/config.yaml
+++ b/test/mainchain/node_miner_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/mainchain/node_miner_1/config.yaml b/test/mainchain/node_miner_1/config.yaml
index 8d88cd5c9..2c49ebd8a 100644
--- a/test/mainchain/node_miner_1/config.yaml
+++ b/test/mainchain/node_miner_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/mainchain/node_miner_2/config.yaml b/test/mainchain/node_miner_2/config.yaml
index 3e67adecf..779402323 100644
--- a/test/mainchain/node_miner_2/config.yaml
+++ b/test/mainchain/node_miner_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/mainchain/node_multi_0/config.yaml b/test/mainchain/node_multi_0/config.yaml
index a0b088db4..e70ffd415 100644
--- a/test/mainchain/node_multi_0/config.yaml
+++ b/test/mainchain/node_multi_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_multi_1/config.yaml b/test/mainchain/node_multi_1/config.yaml
index c92846f87..5c0fc2a6b 100644
--- a/test/mainchain/node_multi_1/config.yaml
+++ b/test/mainchain/node_multi_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_multi_2/config.yaml b/test/mainchain/node_multi_2/config.yaml
index 8d5f46eee..2d1c650f0 100644
--- a/test/mainchain/node_multi_2/config.yaml
+++ b/test/mainchain/node_multi_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/mainchain/node_standalone/config.yaml b/test/mainchain/node_standalone/config.yaml
index a0b088db4..e70ffd415 100644
--- a/test/mainchain/node_standalone/config.yaml
+++ b/test/mainchain/node_standalone/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/node_0/config.yaml b/test/node_0/config.yaml
index 9c2327abb..f47c4cf22 100644
--- a/test/node_0/config.yaml
+++ b/test/node_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/node_1/config.yaml b/test/node_1/config.yaml
index be088389f..4f6a0a249 100644
--- a/test/node_1/config.yaml
+++ b/test/node_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/node_2/config.yaml b/test/node_2/config.yaml
index 0e05b138f..96baa43ea 100644
--- a/test/node_2/config.yaml
+++ b/test/node_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/node_c/config.yaml b/test/node_c/config.yaml
index b23931038..36d58d9ce 100644
--- a/test/node_c/config.yaml
+++ b/test/node_c/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/node_standalone/config.yaml b/test/node_standalone/config.yaml
index b5709bde4..604658ac2 100644
--- a/test/node_standalone/config.yaml
+++ b/test/node_standalone/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/node_standalone/config2.yaml b/test/node_standalone/config2.yaml
index 7921f4cd1..3cd844de8 100644
--- a/test/node_standalone/config2.yaml
+++ b/test/node_standalone/config2.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/observation/node_0/config.yaml b/test/observation/node_0/config.yaml
index 5f28396f8..d47987c9c 100644
--- a/test/observation/node_0/config.yaml
+++ b/test/observation/node_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/observation/node_1/config.yaml b/test/observation/node_1/config.yaml
index 1d4a67dcd..4eef1664a 100644
--- a/test/observation/node_1/config.yaml
+++ b/test/observation/node_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/observation/node_2/config.yaml b/test/observation/node_2/config.yaml
index af8bc1911..91c286918 100644
--- a/test/observation/node_2/config.yaml
+++ b/test/observation/node_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/observation/node_c/config.yaml b/test/observation/node_c/config.yaml
index 098da0e36..569a2bfb5 100644
--- a/test/observation/node_c/config.yaml
+++ b/test/observation/node_c/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/observation/node_miner_0/config.yaml b/test/observation/node_miner_0/config.yaml
index 43934a95e..05d7a724f 100644
--- a/test/observation/node_miner_0/config.yaml
+++ b/test/observation/node_miner_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/observation/node_miner_1/config.yaml b/test/observation/node_miner_1/config.yaml
index 400a21ad9..e49f53b51 100644
--- a/test/observation/node_miner_1/config.yaml
+++ b/test/observation/node_miner_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/observation/node_miner_2/config.yaml b/test/observation/node_miner_2/config.yaml
index edeb37ebc..69e57496a 100644
--- a/test/observation/node_miner_2/config.yaml
+++ b/test/observation/node_miner_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/observation/node_observer/config.yaml b/test/observation/node_observer/config.yaml
index 3a344a39f..55ef693f6 100644
--- a/test/observation/node_observer/config.yaml
+++ b/test/observation/node_observer/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "0000037c786c744967bf536e58d51f24c074f14f693b1daedef88bf9efb92349"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/pool/client.yaml b/test/pool/client.yaml
index 7bc3f1165..342f14f39 100644
--- a/test/pool/client.yaml
+++ b/test/pool/client.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/pool/leader.yaml b/test/pool/leader.yaml
index 400fb667d..a49763f6e 100644
--- a/test/pool/leader.yaml
+++ b/test/pool/leader.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/service/node_0/config.yaml b/test/service/node_0/config.yaml
index b346a58a2..6b5b43471 100644
--- a/test/service/node_0/config.yaml
+++ b/test/service/node_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/service/node_1/config.yaml b/test/service/node_1/config.yaml
index 0c0d2bf5f..38894accc 100644
--- a/test/service/node_1/config.yaml
+++ b/test/service/node_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/service/node_2/config.yaml b/test/service/node_2/config.yaml
index 47d526619..c86182e5c 100644
--- a/test/service/node_2/config.yaml
+++ b/test/service/node_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/service/node_adapter/config.yaml b/test/service/node_adapter/config.yaml
index aeefebf7f..3070a5784 100644
--- a/test/service/node_adapter/config.yaml
+++ b/test/service/node_adapter/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/service/node_c/config.yaml b/test/service/node_c/config.yaml
index aeefebf7f..3070a5784 100644
--- a/test/service/node_c/config.yaml
+++ b/test/service/node_c/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/service/node_miner_0/config.yaml b/test/service/node_miner_0/config.yaml
index 4c981fcb7..ca3f3dd69 100644
--- a/test/service/node_miner_0/config.yaml
+++ b/test/service/node_miner_0/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/service/node_miner_1/config.yaml b/test/service/node_miner_1/config.yaml
index e41bbbb9f..f8aba6764 100644
--- a/test/service/node_miner_1/config.yaml
+++ b/test/service/node_miner_1/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/service/node_miner_2/config.yaml b/test/service/node_miner_2/config.yaml
index 00d4caed0..b3f87924e 100644
--- a/test/service/node_miner_2/config.yaml
+++ b/test/service/node_miner_2/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
BlockProducer:
PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
diff --git a/test/service/node_mysql_adapter/config.yaml b/test/service/node_mysql_adapter/config.yaml
index 3045d1535..37d23a707 100644
--- a/test/service/node_mysql_adapter/config.yaml
+++ b/test/service/node_mysql_adapter/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/test/service/node_observer/config.yaml b/test/service/node_observer/config.yaml
index 9f6dff35a..0e731f457 100644
--- a/test/service/node_observer/config.yaml
+++ b/test/service/node_observer/config.yaml
@@ -8,6 +8,7 @@ ThisNodeID: "0000037c786c744967bf536e58d51f24c074f14f693b1daedef88bf9efb92349"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
MinNodeIDDifficulty: 2
DNSSeed:
EnforcedDNSSEC: false
diff --git a/vendor/github.com/xtaci/smux/stream.go b/vendor/github.com/xtaci/smux/stream.go
index 2ce00d2d9..2a2b82fcc 100644
--- a/vendor/github.com/xtaci/smux/stream.go
+++ b/vendor/github.com/xtaci/smux/stream.go
@@ -146,6 +146,12 @@ func (s *Stream) Close() error {
}
}
+// GetDieCh returns a readonly chan which can be readable
+// when the stream is to be closed.
+func (s *Stream) GetDieCh() <-chan struct{} {
+ return s.die
+}
+
// SetReadDeadline sets the read deadline as defined by
// net.Conn.SetReadDeadline.
// A zero time value disables the deadline.
diff --git a/worker/db.go b/worker/db.go
index ba2c7289f..96095d271 100644
--- a/worker/db.go
+++ b/worker/db.go
@@ -17,9 +17,9 @@
package worker
import (
- "context"
"os"
"path/filepath"
+
//"runtime/trace"
"sync"
"time"
@@ -296,7 +296,7 @@ func (db *Database) writeQuery(request *types.Request) (response *types.Response
// call kayak runtime Process
var result interface{}
- if result, _, err = db.kayakRuntime.Apply(context.Background(), request); err != nil {
+ if result, _, err = db.kayakRuntime.Apply(request.GetContext(), request); err != nil {
err = errors.Wrap(err, "apply failed")
return
}
diff --git a/worker/db_storage.go b/worker/db_storage.go
index b56f6bbee..1b49fce83 100644
--- a/worker/db_storage.go
+++ b/worker/db_storage.go
@@ -19,6 +19,7 @@ package worker
import (
"bytes"
"container/list"
+ "context"
"github.com/CovenantSQL/CovenantSQL/types"
"github.com/CovenantSQL/CovenantSQL/utils"
@@ -99,6 +100,9 @@ func (db *Database) Commit(rawReq interface{}) (result interface{}, err error) {
return
}
+ // reset context, commit should never be canceled
+ req.SetContext(context.Background())
+
// execute
return db.chain.Query(req)
}
diff --git a/worker/db_test.go b/worker/db_test.go
index 36561d5bc..e1689cb0e 100644
--- a/worker/db_test.go
+++ b/worker/db_test.go
@@ -18,6 +18,7 @@ package worker
import (
"bytes"
+ "context"
"fmt"
"io/ioutil"
"math/rand"
@@ -631,6 +632,7 @@ func buildQueryEx(queryType types.QueryType, connID uint64, seqNo uint64, timeSh
Queries: realQueries,
},
}
+ query.SetContext(context.Background())
err = query.Sign(privateKey)
diff --git a/xenomint/sqlite/sqlite.go b/xenomint/sqlite/sqlite.go
index 0ea8bf846..0c2780250 100644
--- a/xenomint/sqlite/sqlite.go
+++ b/xenomint/sqlite/sqlite.go
@@ -18,22 +18,41 @@ package sqlite
import (
"database/sql"
+ "time"
"github.com/CovenantSQL/CovenantSQL/storage"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
"github.com/CovenantSQL/go-sqlite3-encrypt"
)
const (
- serializableDriver = "sqlite3"
+ serializableDriver = "sqlite3-custom"
dirtyReadDriver = "sqlite3-dirty-reader"
)
func init() {
+ sleepFunc := func(t int64) int64 {
+ log.Info("sqlite func sleep start")
+ time.Sleep(time.Duration(t))
+ log.Info("sqlite func sleep end")
+ return t
+ }
sql.Register(dirtyReadDriver, &sqlite3.SQLiteDriver{
ConnectHook: func(c *sqlite3.SQLiteConn) (err error) {
if _, err = c.Exec("PRAGMA read_uncommitted=1", nil); err != nil {
return
}
+ if err = c.RegisterFunc("sleep", sleepFunc, true); err != nil {
+ return
+ }
+ return
+ },
+ })
+ sql.Register(serializableDriver, &sqlite3.SQLiteDriver{
+ ConnectHook: func(c *sqlite3.SQLiteConn) (err error) {
+ if err = c.RegisterFunc("sleep", sleepFunc, true); err != nil {
+ return
+ }
return
},
})
diff --git a/xenomint/state.go b/xenomint/state.go
index 8599cf012..d6a986d61 100644
--- a/xenomint/state.go
+++ b/xenomint/state.go
@@ -17,6 +17,7 @@
package xenomint
import (
+ "context"
"database/sql"
"io"
"strings"
@@ -67,20 +68,21 @@ func NewState(nodeID proto.NodeID, strg xi.Storage) (s *State, err error) {
}
func (s *State) incSeq() {
- s.current++
+ atomic.AddUint64(&s.current, 1)
}
func (s *State) setNextTxID() {
- s.origin = s.current
- s.cmpoint = s.current
+ current := s.getID()
+ s.origin = current
+ s.cmpoint = current
}
func (s *State) setCommitPoint() {
- s.cmpoint = s.current
+ s.cmpoint = s.getID()
}
func (s *State) rollbackID(id uint64) {
- s.current = id
+ atomic.StoreUint64(&s.current, id)
}
// InitTx sets the initial id of the current transaction. This method is not safe for concurrency
@@ -88,7 +90,7 @@ func (s *State) rollbackID(id uint64) {
func (s *State) InitTx(id uint64) {
s.origin = id
s.cmpoint = id
- s.current = id
+ s.rollbackID(id)
s.setSavepoint()
}
@@ -103,14 +105,18 @@ func (s *State) Close(commit bool) (err error) {
}
if s.unc != nil {
if commit {
+ s.Lock()
+ defer s.Unlock()
if err = s.uncCommit(); err != nil {
return
}
} else {
- // Only rollback to last commmit point
+ // Only rollback to last commit point
if err = s.rollback(); err != nil {
return
}
+ s.Lock()
+ defer s.Unlock()
if err = s.uncCommit(); err != nil {
return
}
@@ -199,10 +205,13 @@ func buildTypeNamesFromSQLColumnTypes(types []*sql.ColumnType) (names []string)
type sqlQuerier interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
+ QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
}
func readSingle(
- qer sqlQuerier, q *types.Query) (names []string, types []string, data [][]interface{}, err error,
+ ctx context.Context, qer sqlQuerier, q *types.Query,
+) (
+ names []string, types []string, data [][]interface{}, err error,
) {
var (
rows *sql.Rows
@@ -214,7 +223,7 @@ func readSingle(
if _, pattern, args, err = convertQueryAndBuildArgs(q.Pattern, q.Args); err != nil {
return
}
- if rows, err = qer.Query(pattern, args...); err != nil {
+ if rows, err = qer.QueryContext(ctx, pattern, args...); err != nil {
return
}
defer rows.Close()
@@ -253,6 +262,12 @@ func buildRowsFromNativeData(data [][]interface{}) (rows []types.ResponseRow) {
}
func (s *State) read(req *types.Request) (ref *QueryTracker, resp *types.Response, err error) {
+ return s.readWithContext(context.Background(), req)
+}
+
+func (s *State) readWithContext(
+ ctx context.Context, req *types.Request) (ref *QueryTracker, resp *types.Response, err error,
+) {
var (
ierr error
cnames, ctypes []string
@@ -260,7 +275,7 @@ func (s *State) read(req *types.Request) (ref *QueryTracker, resp *types.Respons
)
// TODO(leventeliu): no need to run every read query here.
for i, v := range req.Payload.Queries {
- if cnames, ctypes, data, ierr = readSingle(s.strg.DirtyReader(), &v); ierr != nil {
+ if cnames, ctypes, data, ierr = readSingle(ctx, s.strg.DirtyReader(), &v); ierr != nil {
err = errors.Wrapf(ierr, "query at #%d failed", i)
// Add to failed pool list
s.pool.setFailed(req)
@@ -288,7 +303,9 @@ func (s *State) read(req *types.Request) (ref *QueryTracker, resp *types.Respons
return
}
-func (s *State) readTx(req *types.Request) (ref *QueryTracker, resp *types.Response, err error) {
+func (s *State) readTx(
+ ctx context.Context, req *types.Request) (ref *QueryTracker, resp *types.Response, err error,
+) {
var (
tx *sql.Tx
id uint64
@@ -297,15 +314,18 @@ func (s *State) readTx(req *types.Request) (ref *QueryTracker, resp *types.Respo
data [][]interface{}
querier sqlQuerier
)
- id = s.getID()
if atomic.LoadUint32(&s.hasSchemaChange) == 1 {
// lock transaction
s.Lock()
defer s.Unlock()
+ id = s.getID()
s.setSavepoint()
querier = s.unc
defer s.rollbackTo(id)
+
+ // TODO(): should detect query type, any timeout write query will cause underlying transaction to rollback
} else {
+ id = s.getID()
if tx, ierr = s.strg.DirtyReader().Begin(); ierr != nil {
err = errors.Wrap(ierr, "open tx failed")
return
@@ -314,8 +334,18 @@ func (s *State) readTx(req *types.Request) (ref *QueryTracker, resp *types.Respo
defer tx.Rollback()
}
+ defer func() {
+ if ctx.Err() != nil {
+ log.WithError(ctx.Err()).WithFields(log.Fields{
+ "req": req,
+ "id": id,
+ "dirtyRead": atomic.LoadUint32(&s.hasSchemaChange) != 1,
+ }).Warning("read query canceled")
+ }
+ }()
+
for i, v := range req.Payload.Queries {
- if cnames, ctypes, data, ierr = readSingle(querier, &v); ierr != nil {
+ if cnames, ctypes, data, ierr = readSingle(ctx, querier, &v); ierr != nil {
err = errors.Wrapf(ierr, "query at #%d failed", i)
// Add to failed pool list
s.pool.setFailed(req)
@@ -343,7 +373,9 @@ func (s *State) readTx(req *types.Request) (ref *QueryTracker, resp *types.Respo
return
}
-func (s *State) writeSingle(q *types.Query) (res sql.Result, err error) {
+func (s *State) writeSingle(
+ ctx context.Context, q *types.Query) (res sql.Result, err error,
+) {
var (
containsDDL bool
pattern string
@@ -353,7 +385,7 @@ func (s *State) writeSingle(q *types.Query) (res sql.Result, err error) {
if containsDDL, pattern, args, err = convertQueryAndBuildArgs(q.Pattern, q.Args); err != nil {
return
}
- if res, err = s.unc.Exec(pattern, args...); err == nil {
+ if res, err = s.unc.ExecContext(ctx, pattern, args...); err == nil {
if containsDDL {
atomic.StoreUint32(&s.hasSchemaChange, 1)
}
@@ -373,7 +405,9 @@ func (s *State) rollbackTo(savepoint uint64) {
s.unc.Exec("ROLLBACK TO \"?\"", savepoint)
}
-func (s *State) write(req *types.Request) (ref *QueryTracker, resp *types.Response, err error) {
+func (s *State) write(
+ ctx context.Context, req *types.Request) (ref *QueryTracker, resp *types.Response, err error,
+) {
var (
savepoint uint64
query = &QueryTracker{Req: req}
@@ -382,6 +416,12 @@ func (s *State) write(req *types.Request) (ref *QueryTracker, resp *types.Respon
lastInsertID int64
)
+ defer func() {
+ if ctx.Err() != nil {
+ log.WithError(err).WithField("req", req).Warning("write query canceled")
+ }
+ }()
+
// TODO(leventeliu): savepoint is a sqlite-specified solution for nested transaction.
if err = func() (err error) {
var ierr error
@@ -390,7 +430,7 @@ func (s *State) write(req *types.Request) (ref *QueryTracker, resp *types.Respon
savepoint = s.getID()
for i, v := range req.Payload.Queries {
var res sql.Result
- if res, ierr = s.writeSingle(&v); ierr != nil {
+ if res, ierr = s.writeSingle(ctx, &v); ierr != nil {
err = errors.Wrapf(ierr, "execute at #%d failed", i)
// Add to failed pool list
s.pool.setFailed(req)
@@ -426,7 +466,7 @@ func (s *State) write(req *types.Request) (ref *QueryTracker, resp *types.Respon
return
}
-func (s *State) replay(req *types.Request, resp *types.Response) (err error) {
+func (s *State) replay(ctx context.Context, req *types.Request, resp *types.Response) (err error) {
var (
ierr error
savepoint uint64
@@ -443,7 +483,7 @@ func (s *State) replay(req *types.Request, resp *types.Response) (err error) {
return
}
for i, v := range req.Payload.Queries {
- if _, ierr = s.writeSingle(&v); ierr != nil {
+ if _, ierr = s.writeSingle(ctx, &v); ierr != nil {
err = errors.Wrapf(ierr, "execute at #%d failed", i)
s.rollbackTo(savepoint)
return
@@ -457,6 +497,12 @@ func (s *State) replay(req *types.Request, resp *types.Response) (err error) {
// ReplayBlock replays the queries from block. It also checks and skips some preceding pooled
// queries.
func (s *State) ReplayBlock(block *types.Block) (err error) {
+ return s.ReplayBlockWithContext(context.Background(), block)
+}
+
+// ReplayBlockWithContext replays the queries from block with context. It also checks and
+// skips some preceding pooled queries.
+func (s *State) ReplayBlockWithContext(ctx context.Context, block *types.Block) (err error) {
var (
ierr error
lastsp uint64 // Last savepoint
@@ -488,7 +534,7 @@ func (s *State) ReplayBlock(block *types.Block) (err error) {
s.rollbackTo(lastsp)
return
}
- if _, ierr = s.writeSingle(&v); ierr != nil {
+ if _, ierr = s.writeSingle(ctx, &v); ierr != nil {
err = errors.Wrapf(ierr, "execute at %d:%d failed", i, j)
s.rollbackTo(lastsp)
return
@@ -501,7 +547,7 @@ func (s *State) ReplayBlock(block *types.Block) (err error) {
for _, r := range block.FailedReqs {
s.pool.removeFailed(r)
}
- // Check if the current transaction is ok to commit
+ // Check if the current transaction is OK to commit
if s.pool.matchLast(lastsp) {
if err = s.uncCommit(); err != nil {
// FATAL ERROR
@@ -541,13 +587,21 @@ func (s *State) commit() (err error) {
// CommitEx commits the current transaction and returns all the pooled queries.
func (s *State) CommitEx() (failed []*types.Request, queries []*QueryTracker, err error) {
+ return s.CommitExWithContext(context.Background())
+}
+
+// CommitExWithContext commits the current transaction and returns all the pooled queries
+// with context.
+func (s *State) CommitExWithContext(
+ ctx context.Context) (failed []*types.Request, queries []*QueryTracker, err error,
+) {
s.Lock()
defer s.Unlock()
if err = s.uncCommit(); err != nil {
// FATAL ERROR
return
}
- if s.unc, err = s.strg.Writer().Begin(); err != nil {
+ if s.unc, err = s.strg.Writer().BeginTx(ctx, nil); err != nil {
// FATAL ERROR
return
}
@@ -575,7 +629,6 @@ func (s *State) rollback() (err error) {
s.Lock()
defer s.Unlock()
s.rollbackTo(s.cmpoint)
- s.current = s.cmpoint
return
}
@@ -586,11 +639,19 @@ func (s *State) getLocalTime() time.Time {
// Query does the query(ies) in req, pools the request and persists any change to
// the underlying storage.
func (s *State) Query(req *types.Request) (ref *QueryTracker, resp *types.Response, err error) {
+ return s.QueryWithContext(context.Background(), req)
+}
+
+// QueryWithContext does the query(ies) in req, pools the request and persists any change to
+// the underlying storage.
+func (s *State) QueryWithContext(
+ ctx context.Context, req *types.Request) (ref *QueryTracker, resp *types.Response, err error,
+) {
switch req.Header.QueryType {
case types.ReadQuery:
- return s.readTx(req)
+ return s.readTx(ctx, req)
case types.WriteQuery:
- return s.write(req)
+ return s.write(ctx, req)
default:
err = ErrInvalidRequest
}
@@ -599,6 +660,13 @@ func (s *State) Query(req *types.Request) (ref *QueryTracker, resp *types.Respon
// Replay replays a write log from other peer to replicate storage state.
func (s *State) Replay(req *types.Request, resp *types.Response) (err error) {
+ return s.ReplayWithContext(context.Background(), req, resp)
+}
+
+// ReplayWithContext replays a write log from other peer to replicate storage state with context.
+func (s *State) ReplayWithContext(
+ ctx context.Context, req *types.Request, resp *types.Response) (err error,
+) {
// NOTE(leventeliu): in the current implementation, failed requests are not tracked in remote
// nodes (while replaying via Replay calls). Because we don't want to actually replay read
// queries in all synchronized nodes, meanwhile, whether a request will fail or not
@@ -609,7 +677,7 @@ func (s *State) Replay(req *types.Request, resp *types.Response) (err error) {
case types.ReadQuery:
return
case types.WriteQuery:
- return s.replay(req, resp)
+ return s.replay(ctx, req, resp)
default:
err = ErrInvalidRequest
}