8
8
#include " chain.h"
9
9
#include " chainparams.h"
10
10
#include " consensus/consensus.h"
11
+ #include " consensus/params.h"
11
12
#include " consensus/validation.h"
12
13
#include " core_io.h"
13
14
#include " init.h"
@@ -303,14 +304,25 @@ static UniValue BIP22ValidationResult(const CValidationState& state)
303
304
return " valid?" ;
304
305
}
305
306
307
+ std::string gbt_vb_name (const Consensus::DeploymentPos pos) {
308
+ const struct BIP9DeploymentInfo & vbinfo = VersionBitsDeploymentInfo[pos];
309
+ std::string s = vbinfo.name ;
310
+ if (!vbinfo.gbt_force ) {
311
+ s.insert (s.begin (), ' !' );
312
+ }
313
+ return s;
314
+ }
315
+
306
316
UniValue getblocktemplate (const UniValue& params, bool fHelp )
307
317
{
308
318
if (fHelp || params.size () > 1 )
309
319
throw runtime_error (
310
320
" getblocktemplate ( \" jsonrequestobject\" )\n "
311
321
" \n If the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n "
312
322
" It returns data needed to construct a block to work on.\n "
313
- " See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n "
323
+ " For full specification, see BIPs 22 and 9:\n "
324
+ " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n "
325
+ " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n "
314
326
315
327
" \n Arguments:\n "
316
328
" 1. \" jsonrequestobject\" (string, optional) A json object in the following spec\n "
@@ -326,6 +338,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
326
338
" \n Result:\n "
327
339
" {\n "
328
340
" \" version\" : n, (numeric) The block version\n "
341
+ " \" rules\" : [ \" rulename\" , ... ], (array of strings) specific block rules that are to be enforced\n "
342
+ " \" vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n "
343
+ " \" rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n "
344
+ " ,...\n "
345
+ " },\n "
346
+ " \" vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n "
329
347
" \" previousblockhash\" : \" xxxx\" , (string) The hash of current highest block\n "
330
348
" \" transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n "
331
349
" {\n "
@@ -369,6 +387,8 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
369
387
370
388
std::string strMode = " template" ;
371
389
UniValue lpval = NullUniValue;
390
+ std::set<std::string> setClientRules;
391
+ int64_t nMaxVersionPreVB = -1 ;
372
392
if (params.size () > 0 )
373
393
{
374
394
const UniValue& oparam = params[0 ].get_obj ();
@@ -412,6 +432,20 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
412
432
TestBlockValidity (state, Params (), block, pindexPrev, false , true );
413
433
return BIP22ValidationResult (state);
414
434
}
435
+
436
+ const UniValue& aClientRules = find_value (oparam, " rules" );
437
+ if (aClientRules.isArray ()) {
438
+ for (unsigned int i = 0 ; i < aClientRules.size (); ++i) {
439
+ const UniValue& v = aClientRules[i];
440
+ setClientRules.insert (v.get_str ());
441
+ }
442
+ } else {
443
+ // NOTE: It is important that this NOT be read if versionbits is supported
444
+ const UniValue& uvMaxVersion = find_value (oparam, " maxversion" );
445
+ if (uvMaxVersion.isNum ()) {
446
+ nMaxVersionPreVB = uvMaxVersion.get_int64 ();
447
+ }
448
+ }
415
449
}
416
450
417
451
if (strMode != " template" )
@@ -501,9 +535,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
501
535
pindexPrev = pindexPrevNew;
502
536
}
503
537
CBlock* pblock = &pblocktemplate->block ; // pointer for convenience
538
+ const Consensus::Params& consensusParams = Params ().GetConsensus ();
504
539
505
540
// Update nTime
506
- UpdateTime (pblock, Params (). GetConsensus () , pindexPrev);
541
+ UpdateTime (pblock, consensusParams , pindexPrev);
507
542
pblock->nNonce = 0 ;
508
543
509
544
UniValue aCaps (UniValue::VARR); aCaps.push_back (" proposal" );
@@ -544,17 +579,69 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
544
579
545
580
arith_uint256 hashTarget = arith_uint256 ().SetCompact (pblock->nBits );
546
581
547
- static UniValue aMutable (UniValue::VARR);
548
- if (aMutable.empty ())
549
- {
550
- aMutable.push_back (" time" );
551
- aMutable.push_back (" transactions" );
552
- aMutable.push_back (" prevblock" );
553
- }
582
+ UniValue aMutable (UniValue::VARR);
583
+ aMutable.push_back (" time" );
584
+ aMutable.push_back (" transactions" );
585
+ aMutable.push_back (" prevblock" );
554
586
555
587
UniValue result (UniValue::VOBJ);
556
588
result.push_back (Pair (" capabilities" , aCaps));
589
+
590
+ UniValue aRules (UniValue::VARR);
591
+ UniValue vbavailable (UniValue::VOBJ);
592
+ for (int i = 0 ; i < (int )Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
593
+ Consensus::DeploymentPos pos = Consensus::DeploymentPos (i);
594
+ ThresholdState state = VersionBitsState (pindexPrev, consensusParams, pos, versionbitscache);
595
+ switch (state) {
596
+ case THRESHOLD_DEFINED:
597
+ case THRESHOLD_FAILED:
598
+ // Not exposed to GBT at all
599
+ break ;
600
+ case THRESHOLD_LOCKED_IN:
601
+ // Ensure bit is set in block version
602
+ pblock->nVersion |= VersionBitsMask (consensusParams, pos);
603
+ // FALL THROUGH to get vbavailable set...
604
+ case THRESHOLD_STARTED:
605
+ {
606
+ const struct BIP9DeploymentInfo & vbinfo = VersionBitsDeploymentInfo[pos];
607
+ vbavailable.push_back (Pair (gbt_vb_name (pos), consensusParams.vDeployments [pos].bit ));
608
+ if (setClientRules.find (vbinfo.name ) == setClientRules.end ()) {
609
+ if (!vbinfo.gbt_force ) {
610
+ // If the client doesn't support this, don't indicate it in the [default] version
611
+ pblock->nVersion &= ~VersionBitsMask (consensusParams, pos);
612
+ }
613
+ }
614
+ break ;
615
+ }
616
+ case THRESHOLD_ACTIVE:
617
+ {
618
+ // Add to rules only
619
+ const struct BIP9DeploymentInfo & vbinfo = VersionBitsDeploymentInfo[pos];
620
+ aRules.push_back (gbt_vb_name (pos));
621
+ if (setClientRules.find (vbinfo.name ) == setClientRules.end ()) {
622
+ // Not supported by the client; make sure it's safe to proceed
623
+ if (!vbinfo.gbt_force ) {
624
+ // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients
625
+ throw JSONRPCError (RPC_INVALID_PARAMETER, strprintf (" Support for '%s' rule requires explicit client support" , vbinfo.name ));
626
+ }
627
+ }
628
+ break ;
629
+ }
630
+ }
631
+ }
557
632
result.push_back (Pair (" version" , pblock->nVersion ));
633
+ result.push_back (Pair (" rules" , aRules));
634
+ result.push_back (Pair (" vbavailable" , vbavailable));
635
+ result.push_back (Pair (" vbrequired" , int (0 )));
636
+
637
+ if (nMaxVersionPreVB >= 2 ) {
638
+ // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here
639
+ // Because BIP 34 changed how the generation transaction is serialised, we can only use version/force back to v2 blocks
640
+ // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated
641
+ // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated
642
+ aMutable.push_back (" version/force" );
643
+ }
644
+
558
645
result.push_back (Pair (" previousblockhash" , pblock->hashPrevBlock .GetHex ()));
559
646
result.push_back (Pair (" transactions" , transactions));
560
647
result.push_back (Pair (" coinbaseaux" , aux));
0 commit comments