diff --git a/cmd/jsutils/getchainstatus.js b/cmd/jsutils/getchainstatus.js index 939b09c183..ee6d050283 100644 --- a/cmd/jsutils/getchainstatus.js +++ b/cmd/jsutils/getchainstatus.js @@ -315,10 +315,53 @@ async function getBinaryVersion() { let turnLength = program.turnLength; for (let i = 0; i < program.num; i++) { let blockData = await provider.getBlock(blockNum - i * turnLength); - // 1.get Geth client version - let major = ethers.toNumber(ethers.dataSlice(blockData.extraData, 2, 3)); - let minor = ethers.toNumber(ethers.dataSlice(blockData.extraData, 3, 4)); - let patch = ethers.toNumber(ethers.dataSlice(blockData.extraData, 4, 5)); + + let major = 0, minor = 0, patch = 0; + let commitID = ""; + + try { + major = ethers.toNumber(ethers.dataSlice(blockData.extraData, 2, 3)); + minor = ethers.toNumber(ethers.dataSlice(blockData.extraData, 3, 4)); + patch = ethers.toNumber(ethers.dataSlice(blockData.extraData, 4, 5)); + + // Check version: >= 1.6.4 uses new format with commitID + const isNewFormat = major > 1 || (major === 1 && minor > 6) || (major === 1 && minor === 6 && patch >= 4); + + if (isNewFormat) { + const extraVanity = 28; + let vanityBytes = ethers.getBytes(ethers.dataSlice(blockData.extraData, 0, extraVanity)); + + let rlpLength = vanityBytes.length; + if (vanityBytes[0] >= 0xC0 && vanityBytes[0] <= 0xF7) { + rlpLength = (vanityBytes[0] - 0xC0) + 1; + } + + const rlpData = ethers.dataSlice(blockData.extraData, 0, rlpLength); + const decoded = ethers.decodeRlp(rlpData); + + if (Array.isArray(decoded) && decoded.length >= 2) { + const secondElemHex = decoded[1]; + let secondElemStr = ""; + try { + secondElemStr = ethers.toUtf8String(secondElemHex); + } catch (e) { + secondElemStr = secondElemHex; + } + + if (secondElemStr.length > 0 && secondElemStr !== "geth") { + commitID = secondElemStr.startsWith("0x") ? secondElemStr.substring(2) : secondElemStr; + } + } + } + } catch (e) { + console.log("Parsing failed:", e.message); + } + + // Format version string + let versionStr = major + "." + minor + "." + patch; + if (commitID && commitID.length > 0) { + versionStr = versionStr + "-" + commitID; + } // 2.get minimum txGasPrice based on the last non-zero-gasprice transaction let lastGasPrice = 0; @@ -332,7 +375,7 @@ async function getBinaryVersion() { break; } var moniker = await getValidatorMoniker(blockData.miner, blockNum); - console.log(blockNum - i * turnLength, blockData.miner, "version =", major + "." + minor + "." + patch, " MinGasPrice = " + lastGasPrice, moniker); + console.log(blockNum - i * turnLength, blockData.miner, "version =", versionStr, " MinGasPrice = " + lastGasPrice, moniker); } } diff --git a/eth/backend.go b/eth/backend.go index a4f6f08586..37312fa5b9 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -28,11 +28,12 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/parlia" "github.com/ethereum/go-ethereum/core" @@ -66,7 +67,6 @@ import ( "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/dnsdisc" "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/triedb/pathdb" @@ -510,12 +510,24 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { func makeExtraData(extra []byte) []byte { if len(extra) == 0 { - // create default extradata + // For version >= 1.6.4, use compact format: [version(uint32), commitID, go_version, os] + commitID := "" + git, ok := version.VCS() + if ok && len(git.Commit) >= 8 { + commitID = git.Commit[:8] + } + + osName := runtime.GOOS + if len(osName) > 3 { + osName = osName[:3] + } + + versionWord := uint32(gethversion.Major<<16 | gethversion.Minor<<8 | gethversion.Patch) extra, _ = rlp.EncodeToBytes([]interface{}{ - uint(gethversion.Major<<16 | gethversion.Minor<<8 | gethversion.Patch), - "geth", + versionWord, + commitID, runtime.Version(), - runtime.GOOS, + osName, }) } if uint64(len(extra)) > params.MaximumExtraDataSize-params.ForkIDSize {