forked from bcosorg/bcos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NonceCheck.cpp
149 lines (108 loc) · 4.03 KB
/
NonceCheck.cpp
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <libethereum/NonceCheck.h>
#include <libdevcore/Common.h>
#include <libdevcore/easylog.h>
using namespace dev;
NonceCheck:: ~NonceCheck()
{
}
u256 NonceCheck::maxblocksize=1000;
void NonceCheck::init(BlockChain const& _bc)
{
m_startblk=0;
m_endblk=0;
updateCache(_bc,true);
}
std::string NonceCheck::generateKey(Transaction const & _t)
{
Address account=_t.from();
std::string key=toHex(account.ref());
key += "_"+toString(_t.randomid());
return key;
}
bool NonceCheck::ok(Transaction const & _transaction,bool _needinsert)
{
DEV_WRITE_GUARDED(m_lock)
{
string key=this->generateKey(_transaction);
auto iter= m_cache.find( key );
if( iter != m_cache.end() )
return false;
if( _needinsert )
{
m_cache.insert(std::pair<std::string,bool>(key,true));
}
}
return true;
}
void NonceCheck::delCache( Transactions const & _transcations)
{
DEV_WRITE_GUARDED(m_lock)
{
for( unsigned i=0;i<_transcations.size();i++)
{
string key=this->generateKey(_transcations[i]);
auto iter= m_cache.find( key );
if( iter != m_cache.end() )
m_cache.erase(iter);
}
}
}
void NonceCheck::updateCache(BlockChain const& _bc,bool _rebuild/*是否强制rebuild */)
{
DEV_WRITE_GUARDED(m_lock)
{
try
{
Timer timer;
unsigned lastnumber=_bc.number();
unsigned prestartblk=m_startblk;
unsigned preendblk=m_endblk;
m_endblk=lastnumber;
if( lastnumber >(unsigned)NonceCheck::maxblocksize )
m_startblk=lastnumber-(unsigned)NonceCheck::maxblocksize;
else
m_startblk=0;
LOG(TRACE)<<"NonceCheck::updateCache m_startblk="<<m_startblk<<",m_endblk="<<m_endblk<<",prestartblk="<<prestartblk<<",preendblk="<<preendblk<<",_rebuild="<<_rebuild;
if( _rebuild )
{
m_cache.clear();
preendblk=0;
}
else
{
for( unsigned i=prestartblk;i<m_startblk;i++)
{
h256 blockhash=_bc.numberHash(i);
std::vector<bytes> bytestrans=_bc.transactions(blockhash);
for( unsigned j=0;j<bytestrans.size();j++)
{
Transaction t = Transaction(bytestrans[j], CheckTransaction::None);
string key=this->generateKey(t);
auto iter= m_cache.find( key );
if( iter != m_cache.end() )
m_cache.erase(iter);
}
}
}
for( unsigned i=std::max(preendblk+1,m_startblk);i<=m_endblk;i++)
{
h256 blockhash=_bc.numberHash(i);
std::vector<bytes> bytestrans=_bc.transactions(blockhash);
for( unsigned j=0;j<bytestrans.size();j++)
{
Transaction t = Transaction(bytestrans[j], CheckTransaction::None);
string key=this->generateKey(t);
auto iter= m_cache.find( key );
if( iter == m_cache.end() )
m_cache.insert(std::pair<std::string,bool>(key,true));
}
}
LOG(TRACE)<<"NonceCheck::updateCache cache size="<<m_cache.size()<<",cost"<<(timer.elapsed() * 1000);
}
catch (...)
{
// should not happen as exceptions
LOG(WARNING) << "o NO!!!! NonceCheck::updateCache " << boost::current_exception_diagnostic_information();
}
}
}//fun