From 95c0e45cfa6dea74bbf8154755c430c299716ae5 Mon Sep 17 00:00:00 2001
From: Alex Sharov <AskAlexSharov@gmail.com>
Date: Thu, 11 Nov 2021 10:17:33 +0700
Subject: [PATCH]  Check existence before write - because WriteRawBody isn't
 idempotent (it allocates new sequence range for transactions on every call)
 (#2941)

---
 eth/stagedsync/stage_bodies.go | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/eth/stagedsync/stage_bodies.go b/eth/stagedsync/stage_bodies.go
index b2fdc1cfdf..362d475e65 100644
--- a/eth/stagedsync/stage_bodies.go
+++ b/eth/stagedsync/stage_bodies.go
@@ -10,6 +10,7 @@ import (
 	libcommon "github.com/ledgerwatch/erigon-lib/common"
 	"github.com/ledgerwatch/erigon-lib/kv"
 	"github.com/ledgerwatch/erigon/common"
+	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/params"
@@ -158,12 +159,20 @@ Loop:
 				u.UnwindTo(blockHeight-1, header.Hash())
 				break Loop
 			}
-			if err = rawdb.WriteRawBody(tx, header.Hash(), blockHeight, rawBody); err != nil {
-				return fmt.Errorf("writing block body: %w", err)
+
+			// Check existence before write - because WriteRawBody isn't idempotent (it allocates new sequence range for transactions on every call)
+			exists, err := tx.Has(kv.BlockBody, dbutils.BlockBodyKey(blockHeight, header.Hash()))
+			if err != nil {
+				return err
+			}
+			if !exists {
+				if err = rawdb.WriteRawBody(tx, header.Hash(), blockHeight, rawBody); err != nil {
+					return fmt.Errorf("writing block body: %w", err)
+				}
 			}
 			if blockHeight > bodyProgress {
 				bodyProgress = blockHeight
-				if err = stages.SaveStageProgress(tx, stages.Bodies, blockHeight); err != nil {
+				if err = s.Update(tx, blockHeight); err != nil {
 					return fmt.Errorf("saving Bodies progress: %w", err)
 				}
 			}
-- 
GitLab