Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Erik Jansen
crown-core-test-new-gitlab-runner
Commits
1fd57e26
Commit
1fd57e26
authored
12 years ago
by
Luke Dashjr
Committed by
Wladimir J. van der Laan
10 years ago
Browse files
Options
Download
Email Patches
Plain Diff
getblocktemplate: longpolling support
parent
7d8faa49
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
src/main.cpp
+5
-0
src/main.cpp
src/main.h
+2
-0
src/main.h
src/rpcmining.cpp
+59
-1
src/rpcmining.cpp
src/rpcserver.cpp
+11
-0
src/rpcserver.cpp
src/rpcserver.h
+2
-0
src/rpcserver.h
src/sync.h
+3
-0
src/sync.h
with
82 additions
and
1 deletion
+82
-1
src/main.cpp
View file @
1fd57e26
...
...
@@ -41,6 +41,8 @@ CCriticalSection cs_main;
map<uint256, CBlockIndex*> mapBlockIndex;
CChain chainActive;
int64_t nTimeBestReceived = 0;
CWaitableCriticalSection csBestBlock;
CConditionVariable cvBlockChange;
int nScriptCheckThreads = 0;
bool fImporting = false;
bool fReindex = false;
...
...
@@ -1944,11 +1946,14 @@ void static UpdateTip(CBlockIndex *pindexNew) {
// New best block
nTimeBestReceived = GetTime();
mempool.AddTransactionsUpdated(1);
LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n",
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
Checkpoints::GuessVerificationProgress(chainActive.Tip()));
cvBlockChange.notify_all();
// Check the version of the last 100 blocks to see if we need to upgrade:
if (!fIsInitialDownload)
{
...
...
This diff is collapsed.
Click to expand it.
src/main.h
View file @
1fd57e26
...
...
@@ -87,6 +87,8 @@ extern uint64_t nLastBlockTx;
extern
uint64_t
nLastBlockSize
;
extern
const
std
::
string
strMessageMagic
;
extern
int64_t
nTimeBestReceived
;
extern
CWaitableCriticalSection
csBestBlock
;
extern
CConditionVariable
cvBlockChange
;
extern
bool
fImporting
;
extern
bool
fReindex
;
extern
bool
fBenchmark
;
...
...
This diff is collapsed.
Click to expand it.
src/rpcmining.cpp
View file @
1fd57e26
...
...
@@ -324,6 +324,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
);
std
::
string
strMode
=
"template"
;
Value
lpval
=
Value
::
null
;
if
(
params
.
size
()
>
0
)
{
const
Object
&
oparam
=
params
[
0
].
get_obj
();
...
...
@@ -336,6 +337,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
}
else
throw
JSONRPCError
(
RPC_INVALID_PARAMETER
,
"Invalid mode"
);
lpval
=
find_value
(
oparam
,
"longpollid"
);
}
if
(
strMode
!=
"template"
)
...
...
@@ -347,8 +349,63 @@ Value getblocktemplate(const Array& params, bool fHelp)
if
(
IsInitialBlockDownload
())
throw
JSONRPCError
(
RPC_CLIENT_IN_INITIAL_DOWNLOAD
,
"Bitcoin is downloading blocks..."
);
// Update block
static
unsigned
int
nTransactionsUpdatedLast
;
if
(
lpval
.
type
()
!=
null_type
)
{
// Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
uint256
hashWatchedChain
;
boost
::
system_time
checktxtime
;
unsigned
int
nTransactionsUpdatedLastLP
;
if
(
lpval
.
type
()
==
str_type
)
{
// Format: <hashBestChain><nTransactionsUpdatedLast>
std
::
string
lpstr
=
lpval
.
get_str
();
hashWatchedChain
.
SetHex
(
lpstr
.
substr
(
0
,
64
));
nTransactionsUpdatedLastLP
=
atoi64
(
lpstr
.
substr
(
64
));
}
else
{
// NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
hashWatchedChain
=
chainActive
.
Tip
()
->
GetBlockHash
();
nTransactionsUpdatedLastLP
=
nTransactionsUpdatedLast
;
}
// Release the wallet and main lock while waiting
#ifdef ENABLE_WALLET
if
(
pwalletMain
)
LEAVE_CRITICAL_SECTION
(
pwalletMain
->
cs_wallet
);
#endif
LEAVE_CRITICAL_SECTION
(
cs_main
);
{
checktxtime
=
boost
::
get_system_time
()
+
boost
::
posix_time
::
minutes
(
1
);
boost
::
unique_lock
<
boost
::
mutex
>
lock
(
csBestBlock
);
while
(
chainActive
.
Tip
()
->
GetBlockHash
()
==
hashWatchedChain
&&
IsRPCRunning
())
{
if
(
!
cvBlockChange
.
timed_wait
(
lock
,
checktxtime
))
{
// Timeout: Check transactions for update
if
(
mempool
.
GetTransactionsUpdated
()
!=
nTransactionsUpdatedLastLP
)
break
;
checktxtime
+=
boost
::
posix_time
::
seconds
(
10
);
}
}
}
ENTER_CRITICAL_SECTION
(
cs_main
);
#ifdef ENABLE_WALLET
if
(
pwalletMain
)
ENTER_CRITICAL_SECTION
(
pwalletMain
->
cs_wallet
);
#endif
if
(
!
IsRPCRunning
())
throw
JSONRPCError
(
RPC_CLIENT_NOT_CONNECTED
,
"Shutting down"
);
// TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
}
// Update block
static
CBlockIndex
*
pindexPrev
;
static
int64_t
nStart
;
static
CBlockTemplate
*
pblocktemplate
;
...
...
@@ -436,6 +493,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
result
.
push_back
(
Pair
(
"transactions"
,
transactions
));
result
.
push_back
(
Pair
(
"coinbaseaux"
,
aux
));
result
.
push_back
(
Pair
(
"coinbasevalue"
,
(
int64_t
)
pblock
->
vtx
[
0
].
vout
[
0
].
nValue
));
result
.
push_back
(
Pair
(
"longpollid"
,
chainActive
.
Tip
()
->
GetBlockHash
().
GetHex
()
+
i64tostr
(
nTransactionsUpdatedLast
)));
result
.
push_back
(
Pair
(
"target"
,
hashTarget
.
GetHex
()));
result
.
push_back
(
Pair
(
"mintime"
,
(
int64_t
)
pindexPrev
->
GetMedianTimePast
()
+
1
));
result
.
push_back
(
Pair
(
"mutable"
,
aMutable
));
...
...
This diff is collapsed.
Click to expand it.
src/rpcserver.cpp
View file @
1fd57e26
...
...
@@ -32,6 +32,7 @@ using namespace std;
static
std
::
string
strRPCUserColonPass
;
static
bool
fRPCRunning
=
false
;
// These are created by StartRPCThreads, destroyed in StopRPCThreads
static
asio
::
io_service
*
rpc_io_service
=
NULL
;
static
map
<
string
,
boost
::
shared_ptr
<
deadline_timer
>
>
deadlineTimers
;
...
...
@@ -659,6 +660,7 @@ void StartRPCThreads()
rpc_worker_group
=
new
boost
::
thread_group
();
for
(
int
i
=
0
;
i
<
GetArg
(
"-rpcthreads"
,
4
);
i
++
)
rpc_worker_group
->
create_thread
(
boost
::
bind
(
&
asio
::
io_service
::
run
,
rpc_io_service
));
fRPCRunning
=
true
;
}
void
StartDummyRPCThread
()
...
...
@@ -671,12 +673,15 @@ void StartDummyRPCThread()
rpc_dummy_work
=
new
asio
::
io_service
::
work
(
*
rpc_io_service
);
rpc_worker_group
=
new
boost
::
thread_group
();
rpc_worker_group
->
create_thread
(
boost
::
bind
(
&
asio
::
io_service
::
run
,
rpc_io_service
));
fRPCRunning
=
true
;
}
}
void
StopRPCThreads
()
{
if
(
rpc_io_service
==
NULL
)
return
;
// Set this to false first, so that longpolling loops will exit when woken up
fRPCRunning
=
false
;
// First, cancel all timers and acceptors
// This is not done automatically by ->stop(), and in some cases the destructor of
...
...
@@ -698,6 +703,7 @@ void StopRPCThreads()
deadlineTimers
.
clear
();
rpc_io_service
->
stop
();
cvBlockChange
.
notify_all
();
if
(
rpc_worker_group
!=
NULL
)
rpc_worker_group
->
join_all
();
delete
rpc_dummy_work
;
rpc_dummy_work
=
NULL
;
...
...
@@ -706,6 +712,11 @@ void StopRPCThreads()
delete
rpc_io_service
;
rpc_io_service
=
NULL
;
}
bool
IsRPCRunning
()
{
return
fRPCRunning
;
}
void
RPCRunHandler
(
const
boost
::
system
::
error_code
&
err
,
boost
::
function
<
void
(
void
)
>
func
)
{
if
(
!
err
)
...
...
This diff is collapsed.
Click to expand it.
src/rpcserver.h
View file @
1fd57e26
...
...
@@ -40,6 +40,8 @@ void StartRPCThreads();
void
StartDummyRPCThread
();
/* Stop RPC threads */
void
StopRPCThreads
();
/* Query whether RPC is running */
bool
IsRPCRunning
();
/*
Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
...
...
This diff is collapsed.
Click to expand it.
src/sync.h
View file @
1fd57e26
...
...
@@ -84,6 +84,9 @@ typedef AnnotatedMixin<boost::recursive_mutex> CCriticalSection;
/** Wrapped boost mutex: supports waiting but not recursive locking */
typedef
AnnotatedMixin
<
boost
::
mutex
>
CWaitableCriticalSection
;
/** Just a typedef for boost::condition_variable, can be wrapped later if desired */
typedef
boost
::
condition_variable
CConditionVariable
;
#ifdef DEBUG_LOCKORDER
void
EnterCritical
(
const
char
*
pszName
,
const
char
*
pszFile
,
int
nLine
,
void
*
cs
,
bool
fTry
=
false
);
void
LeaveCritical
();
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment