This repository has been archived by the owner on Mar 18, 2019. It is now read-only.
/
cutoffcache.go
115 lines (84 loc) · 3.07 KB
/
cutoffcache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ordermanager
import (
"github.com/Loopring/relay/cache"
"github.com/Loopring/relay/ethaccessor"
"github.com/ethereum/go-ethereum/common"
"math/big"
"time"
)
type CutoffCache struct {
ttl int64
}
func NewCutoffCache(expire int64) *CutoffCache {
cutoffcache := &CutoffCache{}
cutoffcache.ttl = expire
return cutoffcache
}
// 合约验证的是创建时间
func (c *CutoffCache) IsOrderCutoff(protocol, owner, token1, token2 common.Address, validsince *big.Int) bool {
if cutoff := c.GetCutoff(protocol, owner); cutoff.Cmp(validsince) > 0 {
return true
}
if cutoff := c.GetCutoffPair(protocol, owner, token1, token2); cutoff.Cmp(validsince) > 0 {
return true
}
return false
}
func (c *CutoffCache) GetCutoff(protocol, owner common.Address) *big.Int {
key := formatCutoffKey(protocol, owner)
if bs, err := cache.Get(key); err == nil {
return bytes2value(bs)
}
if cutoff, _ := ethaccessor.GetCutoff(protocol, owner, "latest"); cutoff.Cmp(big.NewInt(0)) > 0 {
c.UpdateCutoff(protocol, owner, cutoff)
return cutoff
}
return big.NewInt(0)
}
func (c *CutoffCache) GetCutoffPair(protocol, owner, token1, token2 common.Address) *big.Int {
key := formatCutoffPairKey(protocol, owner, token1, token2)
if bs, err := cache.Get(key); err == nil {
return bytes2value(bs)
}
if cutoff, _ := ethaccessor.GetCutoffPair(protocol, owner, token1, token2, "latest"); cutoff.Cmp(big.NewInt(0)) > 0 {
c.UpdateCutoffPair(protocol, owner, token1, token2, cutoff)
return cutoff
}
return big.NewInt(0)
}
func (c *CutoffCache) UpdateCutoff(protocol, owner common.Address, cutoff *big.Int) error {
key := formatCutoffKey(protocol, owner)
bs := value2bytes(cutoff)
return cache.Set(key, bs, time.Now().Unix()+c.ttl)
}
func (c *CutoffCache) UpdateCutoffPair(protocol, owner, token1, token2 common.Address, cutoff *big.Int) error {
key := formatCutoffPairKey(protocol, owner, token1, token2)
bs := value2bytes(cutoff)
return cache.Set(key, bs, time.Now().Unix()+c.ttl)
}
func formatCutoffKey(protocol, owner common.Address) string {
return protocol.Hex() + "-" + owner.Hex()
}
func formatCutoffPairKey(protocol, owner, token1, token2 common.Address) string {
bs := make([]byte, 20)
bs1 := token1.Bytes()
bs2 := token2.Bytes()
for i := 0; i < len(bs1); i++ {
bs[i] = bs1[i] ^ bs2[i]
}
return protocol.Hex() + "-" + owner.Hex() + "-" + string(bs)
}
func value2bytes(v *big.Int) []byte { return v.Bytes() }
func bytes2value(bs []byte) *big.Int { return big.NewInt(0).SetBytes(bs) }