Site icon WSJ-Crypto

Introducing Geth v1.10.0: Enhanced Performance and Exciting Features

Oh my, it’s been quite some time… over 1.5 years since we introduced Geth v1.9.0. We did manage 26 incremental releases during this span (approximately one every three weeks), but releasing a significant update holds a particular significance. The rush of excitement from unveiling new features, combined with the anxiety of potential mishaps. Still uncertain whether I love it or despise it. Regardless, Ethereum is progressing and we must extend our capabilities to keep pace with it.

Without any more delay, please greet Geth v1.10.0 as part of the Ethereum community.

Beware of dragons

Before we delve into the specifics of our latest release, it’s crucial to highlight that new features inherently bring new risks. To accommodate users and projects with varying risk thresholds, many of our significant features can be (for the time being) activated or deactivated individually. Whether you consume the entire content of this blog entry – or only glance over sections that captivate your interest – kindly take a moment to read the ‘Compatibility’ section at the conclusion of this document!

Now that’s addressed, let’s plunge in and explore what Geth v1.10.0 has to offer!

Berlin hard-fork

Let’s address the major issue first. Geth v1.10.0 does not include the Berlin hard-fork yet, as there were some last-minute concerns raised by the Solidity team regarding EIP-2315. Since v1.10.0 represents a major release, we prefer not to launch it too close to the fork. We will follow up shortly with v1.10.1 that will include the finalized list of EIPs and block numbers integrated.

Snapshots

We’ve been discussing snapshots for such an extended period now; it feels surreal to finally witness their presence in a release. Without diving into excessive detail (see linked article), snapshots are an accelerated data structure positioned atop the Ethereum state, enabling accessing accounts and contract storage at a significantly quicker pace.

To quantify this, the snapshot functionality reduces the expense of accessing an account from O(logN) to O(1). This might not appear substantial at first glance, but in practical terms, on the mainnet with 140 million accounts, snapshots can save roughly 8 database lookups per account read. That’s nearly a tenfold reduction in disk lookups, guaranteed to remain constant regardless of state size.

Wait, does this imply we can increase the gas limit by 10x?!– –> Regrettably, no. While snapshots indeed provide a tenfold improvement in read performance, EVM execution also entails writing data, and these writes necessitate Merkle proof. The requirement for Merkle proof maintains the necessity for O(logN) disk access during writes.

Then, what’s the advantage?! While swift read access to accounts and contract storage isn’t adequate to raise the gas limit, it addresses several particularly challenging issues:

  • Denial-of-Service. In 2016, Ethereum endured its most severe DoS attack ever – The Shanghai Attacks – that persisted for about 2-3 months. The attack centered on bloating Ethereum’s state and exploiting various underpriced opcodes to grind the network to a standstill. After multiple client optimizations and repricing hard forks, the assault was thwarted. The underlying issue still remains: state access opcodes incur a fixed EVM gas cost O(1), yet an increasingly weaker execution cost O(logN). We’ve increased the gas costs in Tangerine Whistle, Istanbul, and now Berlin to align the EVM costs with runtime expenses, yet these are merely temporary solutions. Conversely, snapshots reduce the execution cost of state reads to O(1) – in accordance with EVM costs – thereby addressing the read-based DoS concerns long term (don’t hold me to that).
  • Calls. Evaluating a smart contract’s state in Ethereum entails a brief EVM execution. This includes running bytecode and reading state slots from disk. If you operate your personal Ethereum node purely for your own utilization, there’s a good chance the current state access speed suffices. However, if you manage a node for the benefit of multiple users, the tenfold performance enhancement offered by snapshots implies that you can process ten times as many queries at approximately the same cost to you.
  • Synchronization. There are two primary methods to synchronize an Ethereum node. You can download the blocks and execute all corresponding transactions within; or you can download the blocks, confirm the PoWs, and download the state linked to a recent block. The latter method is significantly quicker, but it depends on benefactors supplying you with a copy of the recent state. With the existing Merkle-Patricia state model, these benefactors read 16TB of data off disk to assist a syncing node. With snapshots, serving nodes need only read 96GB of data off disk to integrate a new node into the network. More details on this can be found in the Snap sync section.

As with all features, it’s a matter of trade-offs. Although snapshots offer immense advantages, which we believe are significant enough to make available to everyone, there are certain drawbacks:

  • A snapshot serves as a redundant copy of the raw Ethereum state already present in the leaves of the Merkle Patricia trie. Thus, snapshotsentail an extra disk burden of approximately 20-25GB on mainnet at present. Ideally, snapshots will enable us to implement additional state optimizations and possibly eliminate some of the disk burden of Merkle tries as they exist currently.
  • Given that no one has yet crafted snapshots within the network, nodes will initially need to incur the expense of traversing the state trie and generating the initial snapshot independently. Depending on the traffic to your node, this could take anywhere from one day to a week, but you only have to perform it a single time during the lifespan of your node (assuming everything functions as planned). The snapshot creation operates in the background, simultaneously with all other node processes. We intend to eliminate this requirement once snapshots are universally accessible in the network. More details on this can be found in the Snap sync segment.

If you have reservations about the snapshot capability, you can deactivate it in Geth 1.10.0 through –snapshot=false, but please note that we will make it compulsory in the long run to ensure a fundamental network health.

Snap sync

If you believed snapshots took a considerable period to deliver, just wait until you learn about snap sync! We introduced the preliminary prototype of a novel synchronization algorithm back in October, 2017… and then sat on that concept for over three years?! 🤯 Before proceeding, a brief history recap.

When Ethereum was launched, participants could select between two distinct methods for synchronizing the network: full sync and fast sync (excluding light clients from this conversation). Full sync functioned by downloading the complete chain and processing all transactions; in contrast, fast sync placed trust in a recently confirmed block and directly downloaded the state tied to it (after which it transitioned to block execution similar to full sync). Both operational modes led to the same final dataset, yet they favored different trade-offs:

  • Full sync emphasized minimizing trust, opting to process all transactions from genesis to head. Although it is the most secure alternative, Ethereum mainnet currently comprises over 1.03 billion transactions, increasing at a rate of 1.25 million / day. Choosing to process everything from genesis implies that full sync incurs a continuously growing expense. Presently, processing all those transactions requires 8-10 days on a relatively robust machine.
  • Fast sync chose to depend on the security of the PoWs. Instead of executing every transaction, it operated under the assumption that constructing a block with 64 valid PoWs on top would be excessively costly, thus it’s acceptable to download the state related to HEAD-64. Fast sync relied on the state root from a nearby block, facilitating the direct download of the state trie. This substitution transitioned the need from CPU & disk IO to a requirement for network bandwidth and latency. Specifically, Ethereum mainnet presently consists of around 675 million state trie nodes, taking roughly 8-10 hours to download on a well-connected machine.

Full sync has stayed accessible for anyone who desired to expend the resources to authenticate Ethereum’s complete history, but for the majority of individuals, fast sync proved to be more than satisfactory™. There’s a paradox in computer science that states that once a system exceeds 50 times its intended usage, it will malfunction. The rationale is that regardless of how something functions, apply sufficient pressure and an unexpected bottleneck will emerge.

In the context of fast sync, the unexpected bottleneck was latency, arising from Ethereum’s data structure. Ethereum’s state trie is a Merkle tree, with leaves containing valuable data and each upper node being the hash of 16 children. Syncing from the tree’s root (the hash embedded within a block header) requires requesting each node one-by-one. With 675 million nodes to download, even by combining 384 requests at once, it necessitates 1.75 million round-trips. Assuming an overly generous 50ms RTT to 10 serving peers, fast sync effectively amounts to waiting for over 150 minutes for data to arrive. However, network latency constitutes merely one-third of the issue.

When a serving peer receives a query for trie nodes, it must retrieve them from disk. Ethereum’s Merkle trie does not alleviate this problem either. Since trie nodes are indexed by hash, there’s no significant method to store/retrieve them in batches, with each necessitating its own database read. To exacerbate matters, LevelDB (utilized by Geth) arranges data across 7 levels, meaning a random read will generally involve multiple files. When everything is accounted for, a single network request for 384 nodes—at 7 reads per query—results in 2.7 thousand disk reads. With the fastest SATA SSDs achieving speeds of 100,000 IOPS, this results in an additional 37ms of latency. Assuming the same 10 serving peers as previously mentioned, fast sync has just added an extra waiting time of 108 minutes. But serving latency represents only one-third of the issue.

Requesting that many trie nodes individually necessitates uploading an equal number of hashes to remote peers for servicing. With 675 million nodes to download, that’s 675 million hashes to upload, or 675 * 32 bytes = 21GB. At a global average upload speed of 51Mbps (X Doubt), fast sync has consequently added an extra 56 minutes of waiting time. Downloads are slightly more than double as large, so with global averages of 97Mbps, *fast sync* incurred a further 63 minutes. Bandwidth delays represent the final third of the challenge.

Summing it all up, fast sync ultimately spends an astonishing 6.3 hours not doing anything, merely waiting for data:

  • If your network connection exceeds average performance
  • If you have a good number of serving peers
  • “`html

  • In the event that your associates do not assist anyone else except you

Snap sync was developed to address all three of the outlined issues. The fundamental concept is relatively straightforward: rather than downloading the trie node-by-node, snap sync retrieves contiguous segments of pertinent state data and reconstructs the Merkle trie locally:

  • By avoiding the download of intermediate Merkle trie nodes, state data can be accessed in large batches, eliminating the delay introduced by network latency.
  • By not downloading Merkle nodes, downstream data is reduced by fifty percent; and by neglecting to address each piece of data individually, upstream data becomes negligible, thereby removing the delay caused by bandwidth.
  • By eliminating random key data requests, peers merely perform a couple of contiguous disk reads to provide the responses, thus reducing the delay of disk IO (if the peers already have the data stored in an adequate flat format).

While snap sync is remarkably akin to Parity’s warp sync – and indeed adopted numerous design concepts from it – there are notable enhancements over the latter:

  • Warp sync relies on static snapshots produced every 30,000 blocks. This indicates that serving nodes must regenerate the snapshots every five days or so, although iterating the entire state trie can actually require more time than that. Consequently, warp sync is not sustainable in the long run. In contrast, snap sync is founded on dynamic snapshots, which are generated once, regardless of speed, and are subsequently updated as the chain evolves.
  • Warp sync‘s snapshot structure does not conform to the Merkle trie format, resulting in chunks of warp-data being unable to be individually validated. Syncing nodes must download the complete dataset of over 20GB before they can authenticate it. Consequently, warp syncing nodes could theoretically face issues. Conversely, snap sync‘s snapshot format consists solely of sequential Merkle leaves, facilitating the validation of any range, hence erroneous data is identified immediately.

To quantify snap sync versus fast sync, synchronizing the mainnet state (disregarding blocks and receipts, as those remain the same) against three serving peers, at block ~#11,177,000 yielded the following outcomes:

Please note that snap sync is included, but not yet activated, in Geth v1.10.0. The rationale is that serving snap sync demands nodes to possess the snapshot acceleration infrastructure already constructed, which currently does not exist, as it is also included in v1.10.0. You may manually activate snap sync via –syncmode snap, but be informed that we anticipate it not to locate to suitable peers until a few weeks following Berlin. We will enable it by default when we believe there are sufficient peers to depend on it.

Offline pruning

We’re extremely proud of our accomplishments with Geth over recent years. Nevertheless, there’s always that one subject, which causes you to flinch when queried about. For Geth, that subject is state pruning. But what exactly is pruning and why is it necessary?

When processing a new block, a node takes the current state of the network as input and modifies it according to the transactions in the block, creating a new output state. The output state is primarily the same as the input, with only a few thousand items altered. Because we cannot simply overwrite the previous state (otherwise we would not be able to accommodate block reorganizations), both the old and new states ultimately reside on disk. (Sure, we’re a bit smarter and only write new diffs to disk if they persist and aren’t deleted in the following blocks, but let’s set aside that detail for the moment).

Writing these new pieces of state data, block by block, to the database presents a challenge. They continue to accumulate. In theory, we could “just delete” state data that is old enough not to pose a risk of a reorg, but as it turns out, that’s quite a complex challenge. Given that state in Ethereum is stored in a tree structure – and that most blocks only modify a minor fraction of the state – these trees share substantial portions of the data with each other. We can easily determine if the root of an old trie is outdated and can be removed, but it is exceedingly expensive to ascertain whether a node deep within an old state is still referenced by any newer state.

Over the years, we’ve implemented various pruning algorithms to eliminate leftovers (lost count, around ten), yet we’ve not found a solution that does not fail if sufficient data is presented. Consequently, people have become accustomed to Geth’s database starting lean following a fast sync, and gradually expanding until you become frustrated and resync. This is aggravating to say the least, as re-downloading everything merely wastes bandwidth and contributes unnecessary downtime for the node.

Geth v1.10.0 does not fully remedy the issue, but it represents a significant advancement toward a better user experience. If you have snapshots activated and fully generated, Geth can utilize these as an acceleration framework to relatively swiftly identify which trie nodes should remain and which should be purged. Pruning trie nodes based on snapshots does carry the disadvantage that the chain may not progress during the pruning process. This necessitates stopping Geth, pruning its database, and subsequently restarting it.

In terms of execution time, pruning requires a few hours (greatly depending on your disk speed and accumulated data), with one third dedicated to indexing recent trie nodes from snapshots, one third for deleting outdated trie nodes, and the final third for compacting the database to reclaim
“`freed space. By the conclusion of the procedure, your disk utilization should roughly equal what it would be after a complete synchronization. To trim your database, please execute geth snapshot prune-state.

Please be aware that pruning is a recent and potentially risky feature, a malfunction of which may lead to corrupted blocks. We are assured of its dependability, but if an issue occurs, it’s possible there won’t be a way to recover the database. Our advice – at least until the feature undergoes rigorous testing – is to back up your database before pruning and to experiment with testnet nodes initially prior to fully engaging with mainnet.

Transaction unindexing

Ethereum has been operational for a significant duration, and in its nearly 6 years of existence, Ethereum users have conducted over 1 billion transactions. That’s quite a considerable figure.

Node operators have always assumed they could retrieve any arbitrary transaction from the past using just its hash. To be honest, it seems like an obvious task. However, when crunching the numbers, we find ourselves in an unexpected situation. To make transactions searchable, we must – at the very least – map the complete range of transaction hashes to their respective blocks. Despite all adjustments made to minimize storage, we still have to save 1 block number (4 bytes) linked to 1 hash (32 bytes).

36 bytes per transaction may not appear substantial, but when multiplied with 1 billion transactions, it aggregates to a remarkable 36GB of storage needed to confirm that transaction 0xdeadbeef is located in block N. That’s a significant amount of data and a vast number of database entries to manage. Retaining 36GB seems a reasonable expense if one intends to search transactions from 6 years ago, but practically, most users do not desire this. For them, the additional disk usage and I/O overhead are merely squandered resources. Furthermore, it’s crucial to remember that transaction indices are not included in consensus and do not form part of the network protocol. They are purely a locally generated efficiency mechanism.

Is it feasible to eliminate some – for us – superfluous information from our nodes? Absolutely! Geth v1.10.0 enables transaction unindexing by default and configures it to 2,350,000 blocks (approximately 1 year). The transaction unindexer will operate in the background, and with each new block that arrives, it guarantees that only the transactions from the most recent N blocks are indexed, removing older ones. Should a user choose to access older transactions, they can restart Geth with a higher –txlookuplimit value, and any blocks missing from the updated range will be reindexed (note, the activating event is still block import, so a wait for 1 new block is necessary).

Given that around a third of Ethereum’s transaction volume occurred in 2020, maintaining an entire year’s worth of transaction index will still exert a considerable burden on the database. The aim of transaction unindexing is not to discard an existing feature in the name of conserving space. The objective is to transition towards an operational mode where storage does not expand indefinitely with the history of the chain.

If you wish to turn off transaction unindexing entirely, you can execute Geth with –txlookuplimit=0, which reverts to the previous behavior of keeping the lookup map for every transaction since inception.

Preimage discarding

Ethereum organizes all its data within a Merkle Patricia trie. The values at the leaves represent the raw data being stored (e.g., content of storage slots, account details), while the path to the leaf acts as the key by which the data is stored. However, the keys are not the account addresses or storage addresses; rather they are the Keccak256 hashes of those. This approach helps balance the branch depths of the state tries. Utilizing hashes for keys is adequate as users of Ethereum reference only the original addresses, which can be hashed as needed.

There is one scenario, however, where someone possesses a hash stored in the state trie and wishes to retrieve its preimage: debugging. While traversing EVM bytecode, a developer might desire to examine all the variables within the smart contract. The data is available, but without the preimages, it becomes challenging to identify which data corresponds to which Solidity variable.

Initially, Geth implemented a partially effective solution. We stored in the database all preimages that resulted from user calls (e.g. sending a transaction), but not those emanating from EVM calls (e.g. accessing a storage slot). This was insufficient for Remix, so we enhanced our tracing API to include saving preimages for all SHA3 (Keccak256) operations. Although this resolved the debugging issue for Remix, it prompted inquiries regarding all the data unused by non-debugging nodes.

The preimages are not particularly heavy. If you perform a full sync from inception – re-executing all transactions – you’ll only incur an additional 5GB load. Nonetheless, there is no justification for retaining that data for users who aren’t utilizing it, as it merely increases the load on LevelDB compactions. Therefore, Geth v1.10.0 disables preimage collection by default, yet there is no method to actively eliminate preimages that have already been stored.

If you are utilizing your Geth instance to debug transactions, you can revert to the original behavior using –cache.preimages. Please note, it is not possible to regenerate preimages after the fact. Should you run Geth with preimage collection turned off and have a change of heart, you will need to reimport the blocks.

ETH/66 protocol

The eth/66 protocol is a relatively minor adjustment, yet carries numerous advantageous implications. In essence, the protocol introduces request and response IDs for all bidirectional packets. The intention behind these IDs is to facilitate a simpler alignment of responses to requests, particularly to effectively transmit a response back to the subsystem that initiated the original request.

These IDsare not crucial, and indeed we’ve been successfully navigating around their absence for the last six years. Regrettably, any code that needs to fetch data from the network becomes excessively complex if multiple subsystems can simultaneously request the same type of data. For instance, block headers can be fetched by the downloader synchronizing the chain; it can be fetched by the fetcher handling block announcements; and it can also be requested during fork challenges. Moreover, timeouts can result in delayed or unanticipated deliveries, prompting re-requests. In these scenarios, when a header packet arrives, every subsystem checks the data to determine if it was intended for itself or for another subsystem. Consuming a response that was not designated for a specific subsystem can lead to failures elsewhere that require careful management. It becomes disorganized. Feasible, but disorganized.

The significance of eth/66 in the context of this blog post lies not in its resolution of a specific issue, but rather in the fact that it will be implemented before the Berlin hard-fork. As all nodes are expected to upgrade by the time of the fork, this paves the way for Geth to begin phasing out the outdated protocols following the fork. Only after eliminating all older protocols can we restructure Geth’s internals to utilize request IDs. In line with our protocol deprecation schedule, we intend to discontinue eth/64 soon and eth65 by summer’s end.

Some individuals might view Geth leveraging its influence to enforce protocol updates on other clients. We wish to stress that the typed transactions feature from the Berlin hard-fork originally called for a new protocol version. Since only Geth fully implemented the suite of eth/xy protocols, other clients sought to “hack” it into older protocol versions to avoid focusing on networking at this time. The consensus was that Geth would backport typed transaction support into all its previous protocol code to give other developers time, but in return, would phase out the old versions within 6 months to prevent stagnation.

ChainID enforcement

Back in 2016, when TheDAO hard-fork was enacted, Ethereum introduced the concept of the chain id. The purpose was to adjust the digital signatures on transactions with a distinctive identifier to separate what is valid on Ethereum from what is valid on Ethereum Classic (and what is valid on test networks). Making a transaction valid on one network but not on another guarantees that they cannot be replayed without the owner’s awareness.

To minimize complications during the transition, both new/protected and old/unprotected transactions remained valid. Fast forward five years, and about 15% of transactions on Ethereum still lack replay protection. This does not imply a fundamental vulnerability, unless the same keys are reused across several networks. Top tip: Don’t! Nonetheless, mistakes can occur, and certain Ethereum-based networks have been known to go offline due to replay problems.

Although we do not wish to act as an overseer, we have chosen to encourage individuals and tools to abandon the outdated, unprotected signatures and adopt chain IDs everywhere. The straightforward approach would be to simply invalidate unprotected transactions at the consensus level, but doing so would leave 15% of users seeking emergency fixes. To gradually transition people toward safer alternatives without creating sudden disruptions, Geth v1.10.0 will reject transactions on the RPC that are not replay protected. The propagation through the P2P protocols will remain unchanged for the time being, but we shall advocate for rejection there too in the long run.

If you are utilizing code generated by abigen, we’ve added in the go-ethereum libraries new signer constructors to facilitate the easy creation of chain-id-bound transactors. The legacy signers that were included by default were created prior to EIP155, and until now, you needed to manually construct the protected signer. As this was prone to errors and some assumed we inferred the chain ID internally, we opted to provide direct APIs ourselves. We will phase out and eliminate the legacy signers over the long term.

Recognizing that individuals/tools generating unprotected transactions cannot change overnight, Geth v1.10.0 supports reverting to the previous behavior and accepting non-EIP155 transactions via –rpc.allow-unprotected-txs. Please note that this is a temporary solution that will be removed in the future.

Database introspection

Occasionally, we receive reports of corrupted databases, with no effective means to debug them. Sending a 300GB data directory to us is impractical, and providing custom dissection tools to users is burdensome. Furthermore, since a corrupted database frequently presents itself as an inability to start Geth, even utilizing debugging RPC APIs proves futile.

Geth v1.10.0 comes with a built-in database introspection tool to help ease this situation somewhat. It serves as a very low-level access point to LevelDB, permitting arbitrary data retrievals, insertions, and deletions. We cannot predict how instrumental these will be, but they at least provide a fighting chance to restore a compromised node without necessitating a resync.

The supported commands entail:

  • geth db inspect – Examine the storage size for each type of data in the database
  • geth db stats – Output various database utilization and compaction statistics
  • geth db compact – Compact the database, enhancing read access (very slow)
  • geth db get – Fetch and display the value of a database key
  • geth db delete – Eliminate a database key (extremely perilous)
  • geth db put – Assign the value to a database key (extremely perilous)

Mark deprecations

Within the v1.9.x release lineage, we have designated several CLI flags as deprecated. Some were renamed for improved adherence to our naming standards, while others were eliminated due to discontinued functionalities (particularly Whisper). In the preceding release lineage, we maintained the functionality of the legacy deprecated flags, only displaying a warning when they were utilized instead of the preferred versions.

Geth v1.10.0 utilizes this opportunity to entirely remove support for the previous CLI flags. Below is a compilation to aid you in rectifying your commands if you happen not to have upgraded to the new versions over the last year:

  • –rpc -> –http – Activate the HTTP-RPC server
  • –rpcaddr -> –http.addr – HTTP-RPC server listening interface
  • –rpcport -> –http.port – HTTP-RPC server listening port
  • –rpccorsdomain -> –http.corsdomain – Domain from which to permit requests
  • –rpcvhosts -> –http.vhosts – Virtual hostnames from which to permit requests
  • –rpcapi -> –http.api – APIs provided over the HTTP-RPC interface
  • –wsaddr -> –ws.addr – WS-RPC server listening interface
  • –wsport -> –ws.port – WS-RPC server listening port
  • –wsorigins -> –ws.origins – Origins from which to authorize websockets requests
  • –wsapi -> –ws.api – APIs provided over the WS-RPC interface
  • –gpoblocks -> –gpo.blocks – Number of blocks to inspect for gas prices
  • –gpopercentile -> –gpo.percentile – Percentile of recent transactions to utilize as gas recommendation
  • –graphql.addr -> –graphql – Activate GraphQL on the HTTP-RPC server
  • –graphql.port -> –graphql – Activate GraphQL on the HTTP-RPC server
  • –pprofport -> –pprof.port – Profiler HTTP server listening port
  • –pprofaddr -> –pprof.addr – Profiler HTTP server listening interface
  • –memprofilerate -> –pprof.memprofilerate – Enable memory profiling at the specified rate
  • –blockprofilerate -> –pprof.blockprofilerate – Activate block profiling at the specified rate
  • –cpuprofile -> –pprof.cpuprofile – Record CPU profile to the specified file

A few of the aforementioned legacy flags may continue to function for several releases, but it is inadvisable to depend on their availability.

As the majority of users operating full nodes do not utilize USB wallets through Geth – and considering the peculiarities associated with USB management across different platforms – many node administrators resorted to explicitly disabling USB via –nosub. To align the defaults with the needs of the majority, Geth v1.10.0 has disabled USB wallet support by default and deprecated the –nousb flag. USB wallets can still be used, but explicit request is now required via –usb.

Monitoring unclean shutdowns

We often receive bug reports indicating that Geth began importing legacy blocks upon startup. This issue typically arises when the node operator halts Geth unexpectedly (power failure, OOM killer, overly brief shutdown timeout). Due to Geth maintaining a great deal of uncommitted state in memory – to prevent writing to disk data that may become outdated shortly after – a sudden shutdown can result in these not being flushed. With recent state absent upon startup, Geth is compelled to revert its local chain to the last saved progress point.

In order to eliminate disputes regarding whether an operator shut down their node properly or not, and to prevent a clean cycle following a crash from obscuring the fact that data was lost, Geth v1.10.0 will commence monitoring and reporting node crashes. We are optimistic that this will enable operators to identify misconfigurations or issues within their infrastructure before they escalate into irreversible data loss.

WARN [03-03|06:36:38.734] Unclean shutdown identified        booted=2021-02-03T06:47:28+0000 age=3w6d23h

Compatibility

Executing a significant release so near to a hard fork is not ideal, to put it mildly. Regrettably, delivering all the substantial features for the forthcoming generation Geth required 2 months longer than we initially expected. In an attempt to lessen potential production issues arising from the upgrade, almost every new feature can be disabled via CLI flags. There are still 6 weeks remaining until the anticipated mainnet block to guarantee a seamless experience. Despite this, we apologize for any troubles beforehand.

To revert as much functionality as feasible to the v1.9.x feature-set, kindly execute Geth with:

  • –snapshot=false to deactivate the snapshot acceleration structure and snap sync
  • –txlookuplimit=0 to maintain indexing of all transactions, not merely the past year
  • –cache.preimages to continue generating and preserving account preimages
  • –rpc.allow-unprotected-txs – to permit non-replay-protected signatures
  • –usb – to restore USB wallet support

Please note, the eth_protocolVersion API call is removed as it was illogical. If you possess a valid justification for its necessity, do not hesitate to reach out for discussion.

Epilogue

Like previous major releases, we take great pride in this one too. Although we delayed it significantly, it was done in the interest of stability to ensure that all critical features were thoroughly tested. We are hopeful that this new release family will pave the way for increased transaction throughput along with reduced fees.

As with all our previous releases, you can locate the:



Source link

Exit mobile version