Skip to content

Commit de07b07

Browse files
authored
Merge pull request #29 from renproject/feat/zcash-canopy
Zcash mainnet canopy upgrade
2 parents d316526 + dcc06dd commit de07b07

11 files changed

Lines changed: 157 additions & 199 deletions

File tree

api/server_test.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package api_test
22

33
import (
44
"bytes"
5-
"context"
65
"encoding/json"
76
"fmt"
87
"io/ioutil"
@@ -11,10 +10,9 @@ import (
1110
"time"
1211

1312
. "github.com/onsi/ginkgo"
14-
. "github.com/renproject/mercury/api"
15-
1613
"github.com/renproject/kv"
1714
"github.com/renproject/mercury/api"
15+
. "github.com/renproject/mercury/api"
1816
"github.com/renproject/mercury/cache"
1917
"github.com/renproject/mercury/proxy"
2018
"github.com/renproject/mercury/rpc"
@@ -34,11 +32,8 @@ var _ = Describe("Server", func() {
3432
logger := logrus.StandardLogger()
3533
btcTestnetNodeClient := rpc.NewClient(btcTestnetURL, btcTestnetUser, btcTestnetPassword)
3634
btcTestnetProxy := proxy.NewProxy(btcTestnetNodeClient)
37-
38-
db := kv.NewMemDB(kv.JSONCodec)
39-
store := kv.NewTable(db, "test")
40-
ttl := kv.NewTTLCache(context.Background(), db, "ttl", time.Second)
41-
btcCache := cache.New(store, ttl, logger)
35+
store := kv.NewTable(kv.NewMemDB(kv.JSONCodec), "test")
36+
btcCache := cache.New(store, logger)
4237
btcTestnetAPI := api.NewApi(btctypes.BtcTestnet, btcTestnetProxy, btcCache, logger)
4338
server := NewServer(logrus.StandardLogger(), "5000", btcTestnetAPI)
4439
go server.Run()

cache/cache.go

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,14 @@ var (
2020

2121
type Cache struct {
2222
locks sync.Map
23-
ttl kv.Table
2423
store kv.Table
2524
logger logrus.FieldLogger
2625
}
2726

2827
// New returns a new Cache.
29-
func New(store, ttl kv.Table, logger logrus.FieldLogger) *Cache {
28+
func New(store kv.Table, logger logrus.FieldLogger) *Cache {
3029
return &Cache{
3130
locks: sync.Map{},
32-
ttl: ttl,
3331
store: store,
3432
logger: logger,
3533
}
@@ -39,21 +37,8 @@ func New(store, ttl kv.Table, logger logrus.FieldLogger) *Cache {
3937
// requests that are sent while the result is being retrieved, wait until the first function call returns. This prevents
4038
// the function f() from being called multiple times for the same request.
4139
func (cache *Cache) Get(level types.AccessLevel, hash string, f func() ([]byte, error)) ([]byte, error) {
42-
if level == types.FullAccess {
43-
if cache.ttl == nil {
44-
return f()
45-
}
46-
var data []byte
47-
err := cache.ttl.Get(hash, &data)
48-
if err == kv.ErrKeyNotFound {
49-
value, err := f()
50-
if err != nil {
51-
return nil, err
52-
}
53-
54-
return value, cache.ttl.Insert(hash, value)
55-
}
56-
return data, err
40+
if level == 2 {
41+
return f()
5742
}
5843

5944
// Check if the result already exists in the store.

cache/cache_test.go

Lines changed: 123 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package cache_test
22

33
import (
44
"bytes"
5-
"context"
5+
"encoding/json"
6+
"io/ioutil"
67
"math/rand"
8+
"net/http"
9+
"net/http/httptest"
710
"time"
811

912
. "github.com/onsi/ginkgo"
@@ -19,92 +22,130 @@ var _ = Describe("Cache", func() {
1922
rand.Seed(0)
2023

2124
Context("when sending multiple identical requests", func() {
22-
Context("when the request is of CachedAccess level", func() {
23-
It("should only forward a single request", func() {
24-
db := kv.NewMemDB(kv.JSONCodec)
25-
store := kv.NewTable(db, "test")
26-
ttl := kv.NewTTLCache(context.Background(), db, "ttl", time.Second)
27-
logger := logrus.StandardLogger()
28-
cache := New(store, ttl, logger)
29-
30-
counter := 0
31-
f := func() ([]byte, error) {
32-
counter++
33-
return []byte(time.Now().String()), nil
34-
}
35-
36-
phi.ParForAll(10, func(i int) {
37-
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
38-
_, err := cache.Get(1, "hash", f)
39-
Expect(err).ToNot(HaveOccurred())
40-
})
41-
42-
Expect(counter).To(Equal(1))
43-
})
25+
It("should only forward a single request", func() {
26+
store := kv.NewTable(kv.NewMemDB(kv.JSONCodec), "test")
27+
logger := logrus.StandardLogger()
28+
cache := New(store, logger)
29+
30+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
31+
w.WriteHeader(http.StatusOK)
32+
w.Write([]byte{})
33+
}))
34+
defer server.Close()
4435

45-
It("should return the same result for each request", func() {
46-
db := kv.NewMemDB(kv.JSONCodec)
47-
store := kv.NewTable(db, "test")
48-
ttl := kv.NewTTLCache(context.Background(), db, "ttl", time.Second)
49-
logger := logrus.StandardLogger()
50-
cache := New(store, ttl, logger)
51-
52-
counter := 0
53-
f := func() ([]byte, error) {
54-
counter++
55-
return []byte(time.Now().String()), nil
56-
}
57-
58-
numRequests := 10
59-
responses := make([][]byte, numRequests)
60-
phi.ParForAll(numRequests, func(i int) {
61-
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
62-
resp, err := cache.Get(1, "hash", f)
63-
Expect(err).ToNot(HaveOccurred())
64-
responses[i] = resp
65-
})
66-
for _, resp := range responses {
67-
Expect(bytes.Equal(resp, responses[0])).Should(BeTrue())
68-
}
36+
numRequests := 0
37+
phi.ParBegin(func() {
38+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
39+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
40+
Expect(err).ToNot(HaveOccurred())
41+
}, func() {
42+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
43+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
44+
Expect(err).ToNot(HaveOccurred())
45+
}, func() {
46+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
47+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
48+
Expect(err).ToNot(HaveOccurred())
49+
}, func() {
50+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
51+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
52+
Expect(err).ToNot(HaveOccurred())
53+
}, func() {
54+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
55+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
56+
Expect(err).ToNot(HaveOccurred())
57+
}, func() {
58+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
59+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
60+
Expect(err).ToNot(HaveOccurred())
61+
}, func() {
62+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
63+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
64+
Expect(err).ToNot(HaveOccurred())
65+
}, func() {
66+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
67+
_, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
68+
Expect(err).ToNot(HaveOccurred())
6969
})
70+
71+
Expect(numRequests).To(Equal(1))
7072
})
7173

72-
Context("when the request is FullAccess level", func() {
73-
It("should return the same result for each request and only be forwards once", func() {
74-
db := kv.NewMemDB(kv.JSONCodec)
75-
store := kv.NewTable(db, "test")
76-
ttl := kv.NewTTLCache(context.Background(), db, "ttl", time.Second)
77-
logger := logrus.StandardLogger()
78-
cache := New(store, ttl, logger)
79-
80-
expire := time.After(4 * time.Second)
81-
counter := 0
82-
f := func() ([]byte, error) {
83-
counter++
84-
return []byte(time.Now().String()), nil
85-
}
86-
87-
// Expect result to be cached and only one request will be forwarded
88-
numRequests := 10
89-
responses := make([][]byte, numRequests)
90-
phi.ParForAll(numRequests, func(i int) {
91-
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
92-
resp, err := cache.Get(2, "hash", f)
93-
Expect(err).ToNot(HaveOccurred())
94-
responses[i] = resp
95-
})
96-
Expect(counter).Should(Equal(1))
97-
for _, resp := range responses {
98-
Expect(bytes.Equal(resp, responses[0])).Should(BeTrue())
99-
}
100-
101-
// Expect the result to be expired and the request be forwarded again.
102-
<-expire
103-
resp, err := cache.Get(2, "hash", f)
104-
Expect(err).ToNot(HaveOccurred())
105-
Expect(counter).Should(Equal(2))
106-
Expect(bytes.Equal(resp, responses[0])).ShouldNot(BeTrue())
74+
It("should return the same result for each request", func() {
75+
store := kv.NewTable(kv.NewMemDB(kv.JSONCodec), "test")
76+
logger := logrus.StandardLogger()
77+
cache := New(store, logger)
78+
79+
response := []byte("response")
80+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
81+
w.WriteHeader(http.StatusOK)
82+
w.Write(response)
83+
}))
84+
defer server.Close()
85+
86+
numRequests := 0
87+
phi.ParBegin(func() {
88+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
89+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
90+
Expect(err).ToNot(HaveOccurred())
91+
Expect(resp).To(Equal(response))
92+
}, func() {
93+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
94+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
95+
Expect(err).ToNot(HaveOccurred())
96+
Expect(resp).To(Equal(response))
97+
}, func() {
98+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
99+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
100+
Expect(err).ToNot(HaveOccurred())
101+
Expect(resp).To(Equal(response))
102+
}, func() {
103+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
104+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
105+
Expect(err).ToNot(HaveOccurred())
106+
Expect(resp).To(Equal(response))
107+
}, func() {
108+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
109+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
110+
Expect(err).ToNot(HaveOccurred())
111+
Expect(resp).To(Equal(response))
112+
}, func() {
113+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
114+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
115+
Expect(err).ToNot(HaveOccurred())
116+
Expect(resp).To(Equal(response))
117+
}, func() {
118+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
119+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
120+
Expect(err).ToNot(HaveOccurred())
121+
Expect(resp).To(Equal(response))
122+
}, func() {
123+
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
124+
resp, err := cache.Get(1, "hash", getResponse(server.URL, &numRequests))
125+
Expect(err).ToNot(HaveOccurred())
126+
Expect(resp).To(Equal(response))
107127
})
108128
})
109129
})
110130
})
131+
132+
func getResponse(url string, numRequests *int) func() ([]byte, error) {
133+
return func() ([]byte, error) {
134+
*numRequests++
135+
136+
req := map[string]string{"": ""}
137+
reqBytes, err := json.Marshal(req)
138+
Expect(err).ToNot(HaveOccurred())
139+
140+
resp, err := http.Post(url, "application/json", bytes.NewBuffer(reqBytes))
141+
Expect(err).ToNot(HaveOccurred())
142+
143+
data, err := ioutil.ReadAll(resp.Body)
144+
Expect(err).ToNot(HaveOccurred())
145+
146+
// Add 3 second timeout to simulate latency.
147+
time.Sleep(3 * time.Second)
148+
149+
return data, nil
150+
}
151+
}

cmd/mercury/main.go

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package main
22

33
import (
4-
"context"
54
"os"
6-
"time"
75

86
"github.com/renproject/kv"
97
"github.com/renproject/mercury/api"
@@ -22,25 +20,15 @@ func main() {
2220
db := kv.NewMemDB(kv.JSONCodec)
2321

2422
// Initialise stores.
25-
rinkebyTTL := kv.NewTTLCache(context.Background(), db, "ethRinkebyCache", 5*time.Second)
26-
kovanTTL := kv.NewTTLCache(context.Background(), db, "ethKovanCache", 5*time.Second)
27-
// btcTestTTL := kv.NewTTLCache(context.Background(), db, "btcTestCache", 5*time.Second)
28-
// zecTestTTL := kv.NewTTLCache(context.Background(), db, "zecTestCache", 5*time.Second)
29-
// bchTestTTL := kv.NewTTLCache(context.Background(), db, "bchTestCache", 5*time.Second)
30-
// ethTTL := kv.NewTTLCache(context.Background(), db, "ethCache", 5*time.Second)
31-
// btcTTL := kv.NewTTLCache(context.Background(), db, "btcCache", 5*time.Second)
32-
// zecTTL := kv.NewTTLCache(context.Background(), db, "zecCache", 5*time.Second)
33-
// bchTTL := kv.NewTTLCache(context.Background(), db, "bchCache", 5*time.Second)
34-
35-
ethRinkebyCache := cache.New(kv.NewTable(db, "ethRinkeby"), rinkebyTTL, logger)
36-
ethKovanCache := cache.New(kv.NewTable(db, "ethKovan"), kovanTTL, logger)
37-
btcTestCache := cache.New(kv.NewTable(db, "btcTest"), nil, logger)
38-
zecTestCache := cache.New(kv.NewTable(db, "zecTest"), nil, logger)
39-
bchTestCache := cache.New(kv.NewTable(db, "bchTest"), nil, logger)
40-
ethCache := cache.New(kv.NewTable(db, "eth"), nil, logger)
41-
btcCache := cache.New(kv.NewTable(db, "btc"), nil, logger)
42-
zecCache := cache.New(kv.NewTable(db, "zec"), nil, logger)
43-
bchCache := cache.New(kv.NewTable(db, "bch"), nil, logger)
23+
ethRinkebyCache := cache.New(kv.NewTable(db, "ethRinkeby"), logger)
24+
ethKovanCache := cache.New(kv.NewTable(db, "ethKovan"), logger)
25+
btcTestCache := cache.New(kv.NewTable(db, "btcTest"), logger)
26+
zecTestCache := cache.New(kv.NewTable(db, "zecTest"), logger)
27+
bchTestCache := cache.New(kv.NewTable(db, "bchTest"), logger)
28+
ethCache := cache.New(kv.NewTable(db, "eth"), logger)
29+
btcCache := cache.New(kv.NewTable(db, "btc"), logger)
30+
zecCache := cache.New(kv.NewTable(db, "zec"), logger)
31+
bchCache := cache.New(kv.NewTable(db, "bch"), logger)
4432

4533
// Initialise Bitcoin API.
4634
btcTestnetURL := os.Getenv("BITCOIN_TESTNET_RPC_URL")

go.mod

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,25 @@ module github.com/renproject/mercury
33
go 1.12
44

55
require (
6-
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
76
github.com/allegro/bigcache v1.2.1 // indirect
87
github.com/aristanetworks/goarista v0.0.0-20200310212843-2da4c1f5881b // indirect
98
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a
109
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
1110
github.com/cespare/cp v1.1.1 // indirect
1211
github.com/codahale/blake2 v0.0.0-20150924215134-8d10d0420cbf
1312
github.com/deckarep/golang-set v1.7.1 // indirect
14-
github.com/dgraph-io/badger v1.6.1 // indirect
15-
github.com/dgraph-io/ristretto v0.0.3 // indirect
16-
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
1713
github.com/edsrzf/mmap-go v1.0.0 // indirect
1814
github.com/elastic/gosigar v0.10.5 // indirect
1915
github.com/ethereum/go-ethereum v1.9.5
2016
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
2117
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
22-
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
23-
github.com/golang/protobuf v1.4.2 // indirect
2418
github.com/gorilla/mux v1.7.3
2519
github.com/gorilla/websocket v1.4.1 // indirect
2620
github.com/hashicorp/golang-lru v0.5.4 // indirect
2721
github.com/huin/goupnp v1.0.0 // indirect
2822
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
2923
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
30-
github.com/mattn/go-colorable v0.1.7 // indirect
24+
github.com/mattn/go-colorable v0.1.8 // indirect
3125
github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20190720004541-5f6b3168e4a0
3226
github.com/olekukonko/tablewriter v0.0.4 // indirect
3327
github.com/onsi/ginkgo v1.10.1
@@ -45,10 +39,7 @@ require (
4539
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
4640
github.com/tyler-smith/go-bip39 v1.0.2
4741
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
48-
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
49-
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
50-
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 // indirect
51-
google.golang.org/protobuf v1.25.0 // indirect
42+
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
5243
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
5344
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect
5445
gopkg.in/urfave/cli.v1 v1.20.0 // indirect

0 commit comments

Comments
 (0)