From 748321eb5ba709feed716a3ccd0624a27767119f Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 13 Nov 2015 15:35:04 -0500 Subject: [PATCH 1/4] Add mediantime field to getblockchaininfo RPC call Useful now that BIP113 is enforced for transactions entering the mempool. Was previously only (indirectly) available by calling getblocktemplate, a relatively expensive RPC call. --- src/rpcblockchain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 9c0e78f77..bc86e181c 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -639,6 +639,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); From c277a63ed70d063541e1e939917159129c102fec Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 13 Nov 2015 16:36:54 -0500 Subject: [PATCH 2/4] Clarify nLockTime-by-time comment in CheckFinalTx() --- src/main.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5208fbb03..baef017dc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -670,10 +670,11 @@ bool CheckFinalTx(const CTransaction &tx, int flags) // IsFinalTx() with one more than chainActive.Height(). const int nBlockHeight = chainActive.Height() + 1; - // Timestamps on the other hand don't get any special treatment, - // because we can't know what timestamp the next block will have, - // and there aren't timestamp applications where it matters. - // However this changes once median past time-locks are enforced: + // BIP113 will require that time-locked transactions have nLockTime set to + // less than the median time of the previous block they're contained in. + // When the next block is created its previous block will be the current + // chain tip, so we use that to calculate the median time passed to + // IsFinalTx() if LOCKTIME_MEDIAN_TIME_PAST is set. const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST) ? chainActive.Tip()->GetMedianTimePast() : GetAdjustedTime(); From 7259769d7f47c550a2c136585d94dc0e1dac24ff Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 13 Nov 2015 16:49:47 -0500 Subject: [PATCH 3/4] Document new mediantime field in getblockchaininfo --- src/rpcblockchain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index bc86e181c..989fc3704 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -608,6 +608,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" + " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" From 6531f17a78e1e22c441d254eab83ce0a6d72b044 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 13 Nov 2015 16:57:10 -0500 Subject: [PATCH 4/4] Add mediantime field to getblock and getblockheader --- src/rpcblockchain.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 989fc3704..012370ed1 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -71,6 +71,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) result.push_back(Pair("version", blockindex->nVersion)); result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); result.push_back(Pair("time", (int64_t)blockindex->nTime)); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); @@ -111,6 +112,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx } result.push_back(Pair("tx", txs)); result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); result.push_back(Pair("nonce", (uint64_t)block.nNonce)); result.push_back(Pair("bits", strprintf("%08x", block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); @@ -313,6 +315,7 @@ UniValue getblockheader(const UniValue& params, bool fHelp) " \"version\" : n, (numeric) The block version\n" " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"nonce\" : n, (numeric) The nonce\n" " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" @@ -374,6 +377,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " ,...\n" " ],\n" " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"nonce\" : n, (numeric) The nonce\n" " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n"