diff --git a/.github/workflows/qa-constrained-tip-tracking.yml b/.github/workflows/qa-constrained-tip-tracking.yml
index b0b6d4505a7..434e2c39f45 100644
--- a/.github/workflows/qa-constrained-tip-tracking.yml
+++ b/.github/workflows/qa-constrained-tip-tracking.yml
@@ -7,15 +7,26 @@ on:
jobs:
constrained-tip-tracking-test:
- runs-on: [self-hosted, Erigon3]
timeout-minutes: 600
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - chain: mainnet
+ backend: Erigon3
+ cgroup_name: constrained_res_32G
+ - chain: bor-mainnet
+ backend: Polygon
+ cgroup_name: constrained_res_64G
+ runs-on: [ self-hosted, "${{ matrix.backend }}" ]
env:
ERIGON_REFERENCE_DATA_DIR: /opt/erigon-versions/reference-version/datadir
ERIGON_TESTBED_DATA_DIR: /opt/erigon-testbed/datadir
ERIGON_QA_PATH: /home/qarunner/erigon-qa
TRACKING_TIME_SECONDS: 14400 # 4 hours
TOTAL_TIME_SECONDS: 28800 # 8 hours
- CHAIN: mainnet
+ CHAIN: ${{ matrix.chain }}
+ CGROUP_NAME: ${{ matrix.cgroup_name }}
steps:
- name: Check out repository
@@ -44,15 +55,15 @@ jobs:
set +e # Disable exit on error
# Run Erigon under memory constraints, wait sync and check ability to maintain sync
- cgexec -g memory:constrained_res_32G python3 $ERIGON_QA_PATH/test_system/qa-tests/tip-tracking/run_and_check_tip_tracking.py \
+ cgexec -g memory:$CGROUP_NAME python3 $ERIGON_QA_PATH/test_system/qa-tests/tip-tracking/run_and_check_tip_tracking.py \
${{ github.workspace }}/build/bin $ERIGON_TESTBED_DATA_DIR $TRACKING_TIME_SECONDS $TOTAL_TIME_SECONDS Erigon3 $CHAIN standard_node statistics
# Capture monitoring script exit status
test_exit_status=$?
# Save the subsection reached status
- echo "::set-output name=test_executed::true"
-
+ echo "test_executed=true" >> $GITHUB_OUTPUT
+
# Clean up Erigon process if it's still running
if kill -0 $ERIGON_PID 2> /dev/null; then
echo "Terminating Erigon"
@@ -94,14 +105,14 @@ jobs:
if: steps.test_step.outputs.test_executed == 'true'
uses: actions/upload-artifact@v4
with:
- name: test-results
+ name: test-results-${{ env.CHAIN }}
path: ${{ github.workspace }}/result-${{ env.CHAIN }}.json
- name: Upload Erigon full log
if: steps.test_step.outputs.test_executed == 'true'
uses: actions/upload-artifact@v4
with:
- name: erigon-log
+ name: erigon-log-${{ env.CHAIN }}
path: |
${{ env.ERIGON_TESTBED_DATA_DIR }}/logs/erigon.log
${{ env.ERIGON_TESTBED_DATA_DIR }}/proc_stat.log
diff --git a/.github/workflows/scripts/run_rpc_tests.sh b/.github/workflows/scripts/run_rpc_tests.sh
index 64dfe5d1975..74e68533e7b 100755
--- a/.github/workflows/scripts/run_rpc_tests.sh
+++ b/.github/workflows/scripts/run_rpc_tests.sh
@@ -19,6 +19,8 @@ disabled_tests=(
eth_coinbase/test_01.json
eth_createAccessList/test_16.json
eth_getTransactionByHash/test_02.json
+ # Small prune issue that leads to wrong ReceiptDomain data at 16999999 (probably at every million) block: https://github.com/erigontech/erigon/issues/13050
+ ots_searchTransactionsBefore/test_04.tar
eth_getWork/test_01.json
eth_mining/test_01.json
eth_protocolVersion/test_1.json
diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index 4b513cc8f60..bada5001cb0 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -207,7 +207,7 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract libcommon.Addres
}
defer tx.Rollback()
stateDB := b.stateByBlockNumber(tx, blockNumber)
- return stateDB.GetCode(contract), nil
+ return stateDB.GetCode(contract)
}
// BalanceAt returns the wei balance of a certain account in the blockchain.
@@ -220,7 +220,7 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract libcommon.Add
}
defer tx.Rollback()
stateDB := b.stateByBlockNumber(tx, blockNumber)
- return stateDB.GetBalance(contract), nil
+ return stateDB.GetBalance(contract)
}
// NonceAt returns the nonce of a certain account in the blockchain.
@@ -234,7 +234,7 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract libcommon.Addre
defer tx.Rollback()
stateDB := b.stateByBlockNumber(tx, blockNumber)
- return stateDB.GetNonce(contract), nil
+ return stateDB.GetNonce(contract)
}
// StorageAt returns the value of key in the storage of an account in the blockchain.
@@ -265,7 +265,7 @@ func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash libcom
defer tx.Rollback()
// Retrieve the context of the receipt based on the transaction hash
- blockNumber, err := rawdb.ReadTxLookupEntry(tx, txHash)
+ blockNumber, _, err := rawdb.ReadTxLookupEntry(tx, txHash)
if err != nil {
return nil, err
}
@@ -308,7 +308,7 @@ func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash libcomm
if txn != nil {
return txn, true, nil
}
- blockNumber, ok, err := b.BlockReader().TxnLookup(ctx, tx, txHash)
+ blockNumber, _, ok, err := b.BlockReader().TxnLookup(ctx, tx, txHash)
if err != nil {
return nil, false, err
}
@@ -518,7 +518,7 @@ func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract libcommon
b.mu.Lock()
defer b.mu.Unlock()
- return b.pendingState.GetCode(contract), nil
+ return b.pendingState.GetCode(contract)
}
func newRevertError(result *evmtypes.ExecutionResult) *revertError {
@@ -600,7 +600,7 @@ func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account libcommon
b.mu.Lock()
defer b.mu.Unlock()
- return b.pendingState.GetNonce(account), nil
+ return b.pendingState.GetNonce(account)
}
// SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated
@@ -628,7 +628,10 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
}
// Recap the highest gas allowance with account's balance.
if call.GasPrice != nil && !call.GasPrice.IsZero() {
- balance := b.pendingState.GetBalance(call.From) // from can't be nil
+ balance, err := b.pendingState.GetBalance(call.From) // from can't be nil
+ if err != nil {
+ return 0, err
+ }
available := balance.ToBig()
if call.Value != nil {
if call.Value.ToBig().Cmp(available) >= 0 {
@@ -724,7 +727,10 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg
call.Value = new(uint256.Int)
}
// Set infinite balance to the fake caller account.
- from := statedb.GetOrNewStateObject(call.From)
+ from, err := statedb.GetOrNewStateObject(call.From)
+ if err != nil {
+ return nil, err
+ }
from.SetBalance(uint256.NewInt(0).SetAllOne(), tracing.BalanceChangeUnspecified)
// Execute the call.
msg := callMsg{call}
@@ -752,7 +758,10 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, txn types.Transa
if senderErr != nil {
return fmt.Errorf("invalid transaction: %w", senderErr)
}
- nonce := b.pendingState.GetNonce(sender)
+ nonce, err := b.pendingState.GetNonce(sender)
+ if err != nil {
+ return err
+ }
if txn.GetNonce() != nonce {
return fmt.Errorf("invalid transaction nonce: got %d, want %d", txn.GetNonce(), nonce)
}
diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go
index 841548f47d5..fdb8bd76494 100644
--- a/accounts/abi/bind/backends/simulated_test.go
+++ b/accounts/abi/bind/backends/simulated_test.go
@@ -89,7 +89,7 @@ func TestSimulatedBackend(t *testing.T) {
sim.Commit()
_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
if err != nil {
- t.Fatalf("error getting transaction with hash: %v", txHash.String())
+ t.Fatalf("error getting transaction with hash: %v %v", txHash.String(), err.Error())
}
if isPending {
t.Fatal("transaction should not have pending status")
@@ -152,7 +152,10 @@ func TestNewSimulatedBackend(t *testing.T) {
}
statedb := sim.stateByBlockNumber(tx, new(big.Int).SetUint64(num+1))
- bal := statedb.GetBalance(testAddr)
+ bal, err := statedb.GetBalance(testAddr)
+ if err != nil {
+ t.Fatal(err)
+ }
if !bal.Eq(expectedBal) {
t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
}
diff --git a/cl/antiquary/antiquary.go b/cl/antiquary/antiquary.go
index 1f36f508969..22a42c16aab 100644
--- a/cl/antiquary/antiquary.go
+++ b/cl/antiquary/antiquary.go
@@ -32,6 +32,7 @@ import (
"github.com/erigontech/erigon-lib/downloader/snaptype"
proto_downloader "github.com/erigontech/erigon-lib/gointerfaces/downloaderproto"
"github.com/erigontech/erigon-lib/kv"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/persistence/beacon_indicies"
"github.com/erigontech/erigon/cl/persistence/blob_storage"
@@ -62,12 +63,13 @@ type Antiquary struct {
validatorsTable *state_accessors.StaticValidatorTable
genesisState *state.CachingBeaconState
+ syncedData synced_data.SyncedData
// set to nil
currentState *state.CachingBeaconState
balances32 []byte
}
-func NewAntiquary(ctx context.Context, blobStorage blob_storage.BlobStorage, genesisState *state.CachingBeaconState, validatorsTable *state_accessors.StaticValidatorTable, cfg *clparams.BeaconChainConfig, dirs datadir.Dirs, downloader proto_downloader.DownloaderClient, mainDB kv.RwDB, stateSn *snapshotsync.CaplinStateSnapshots, sn *freezeblocks.CaplinSnapshots, reader freezeblocks.BeaconSnapshotReader, logger log.Logger, states, blocks, blobs, snapgen bool, snBuildSema *semaphore.Weighted) *Antiquary {
+func NewAntiquary(ctx context.Context, blobStorage blob_storage.BlobStorage, genesisState *state.CachingBeaconState, validatorsTable *state_accessors.StaticValidatorTable, cfg *clparams.BeaconChainConfig, dirs datadir.Dirs, downloader proto_downloader.DownloaderClient, mainDB kv.RwDB, stateSn *snapshotsync.CaplinStateSnapshots, sn *freezeblocks.CaplinSnapshots, reader freezeblocks.BeaconSnapshotReader, syncedData synced_data.SyncedData, logger log.Logger, states, blocks, blobs, snapgen bool, snBuildSema *semaphore.Weighted) *Antiquary {
backfilled := &atomic.Bool{}
blobBackfilled := &atomic.Bool{}
backfilled.Store(false)
@@ -92,6 +94,7 @@ func NewAntiquary(ctx context.Context, blobStorage blob_storage.BlobStorage, gen
blobs: blobs,
snapgen: snapgen,
stateSn: stateSn,
+ syncedData: syncedData,
}
}
@@ -214,6 +217,14 @@ func (a *Antiquary) Loop() error {
}
}
+ if a.stateSn != nil {
+ if err := a.stateSn.OpenFolder(); err != nil {
+ return err
+ }
+ }
+ log.Info("[Caplin] Stat", "blocks-static", a.sn.BlocksAvailable(), "states-static", a.stateSn.BlocksAvailable(), "blobs-static", a.sn.FrozenBlobs(),
+ "state-history-enabled", a.states, "block-history-enabled", a.blocks, "blob-history-enabled", a.blobs, "snapgen", a.snapgen)
+
frozenSlots := a.sn.BlocksAvailable()
if frozenSlots != 0 {
if err := beacon_indicies.PruneBlocks(a.ctx, tx, frozenSlots); err != nil {
diff --git a/cl/antiquary/state_antiquary.go b/cl/antiquary/state_antiquary.go
index 253b5d9aeb3..4e6cb2e9412 100644
--- a/cl/antiquary/state_antiquary.go
+++ b/cl/antiquary/state_antiquary.go
@@ -57,11 +57,11 @@ func (s *Antiquary) loopStates(ctx context.Context) {
// Execute this each second
reqRetryTimer := time.NewTicker(100 * time.Millisecond)
defer reqRetryTimer.Stop()
+
if !initial_state.IsGenesisStateSupported(clparams.NetworkType(s.cfg.DepositNetworkID)) {
s.logger.Warn("Genesis state is not supported for this network, no historical states data will be available")
return
}
-
_, beforeFinalized, err := s.readHistoricalProcessingProgress(ctx)
if err != nil {
s.logger.Error("Failed to read historical processing progress", "err", err)
@@ -81,11 +81,16 @@ func (s *Antiquary) loopStates(ctx context.Context) {
s.logger.Error("Failed to read historical processing progress", "err", err)
continue
}
+ if s.sn == nil || s.syncedData.Syncing() {
+ continue
+ }
+
// We wait for updated finality.
if finalized == beforeFinalized {
continue
}
beforeFinalized = finalized
+
if err := s.IncrementBeaconState(ctx, finalized); err != nil {
if s.currentState != nil {
s.logger.Warn("Could not to increment beacon state, trying again later", "err", err, "slot", s.currentState.Slot())
@@ -137,9 +142,16 @@ func FillStaticValidatorsTableIfNeeded(ctx context.Context, logger log.Logger, s
blocksAvaiable := stateSn.BlocksAvailable()
stateSnRoTx := stateSn.View()
defer stateSnRoTx.Close()
-
+ log.Info("[Caplin-Archive] filling validators table", "from", 0, "to", stateSn.BlocksAvailable())
+ logTicker := time.NewTicker(10 * time.Second)
+ defer logTicker.Stop()
start := time.Now()
for slot := uint64(0); slot <= stateSn.BlocksAvailable(); slot++ {
+ select {
+ case <-logTicker.C:
+ log.Info("[Caplin-Archive] Filled validators table", "progress", fmt.Sprintf("%d/%d", slot, stateSn.BlocksAvailable()))
+ default:
+ }
seg, ok := stateSnRoTx.VisibleSegment(slot, kv.StateEvents)
if !ok {
return false, fmt.Errorf("segment not found for slot %d", slot)
@@ -434,7 +446,7 @@ func (s *Antiquary) IncrementBeaconState(ctx context.Context, to uint64) error {
// We now do some post-processing on the state.
select {
case <-progressTimer.C:
- log.Log(logLvl, "State processing progress", "slot", slot, "blk/sec", fmt.Sprintf("%.2f", float64(slot-prevSlot)/60))
+ log.Log(logLvl, "[Caplin-Archive] Historical States reconstruction", "slot", slot, "blk/sec", fmt.Sprintf("%.2f", float64(slot-prevSlot)/60))
prevSlot = slot
default:
}
@@ -488,7 +500,7 @@ func (s *Antiquary) IncrementBeaconState(ctx context.Context, to uint64) error {
return err
}
- log.Info("Historical states antiquated", "slot", s.currentState.Slot(), "root", libcommon.Hash(stateRoot), "latency", endTime)
+ log.Info("[Caplin-Archive] Historical states antiquated", "slot", s.currentState.Slot(), "root", libcommon.Hash(stateRoot), "latency", endTime)
if s.stateSn != nil {
if err := s.stateSn.OpenFolder(); err != nil {
return err
@@ -574,7 +586,7 @@ func (s *Antiquary) initializeStateAntiquaryIfNeeded(ctx context.Context, tx kv.
backoffStrides := uint64(10)
backoffStep := backoffStrides
- historicalReader := historical_states_reader.NewHistoricalStatesReader(s.cfg, s.snReader, s.validatorsTable, s.genesisState, s.stateSn)
+ historicalReader := historical_states_reader.NewHistoricalStatesReader(s.cfg, s.snReader, s.validatorsTable, s.genesisState, s.stateSn, s.syncedData)
for {
attempt, err := computeSlotToBeRequested(tx, s.cfg, s.genesisState.Slot(), targetSlot, backoffStep)
diff --git a/cl/antiquary/state_antiquary_test.go b/cl/antiquary/state_antiquary_test.go
index 4be4b442302..c30ff84a75f 100644
--- a/cl/antiquary/state_antiquary_test.go
+++ b/cl/antiquary/state_antiquary_test.go
@@ -30,6 +30,7 @@ import (
"github.com/erigontech/erigon-lib/kv/memdb"
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/cl/antiquary/tests"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/cltypes"
state_accessors "github.com/erigontech/erigon/cl/persistence/state"
@@ -39,13 +40,19 @@ import (
func runTest(t *testing.T, blocks []*cltypes.SignedBeaconBlock, preState, postState *state.CachingBeaconState) {
db := memdb.NewTestDB(t, kv.ChainDB)
reader := tests.LoadChain(blocks, postState, db, t)
-
+ sn := synced_data.NewSyncedDataManager(&clparams.MainnetBeaconConfig, true)
+ sn.OnHeadState(postState)
ctx := context.Background()
vt := state_accessors.NewStaticValidatorTable()
- a := NewAntiquary(ctx, nil, preState, vt, &clparams.MainnetBeaconConfig, datadir.New("/tmp"), nil, db, nil, nil, reader, log.New(), true, true, true, false, nil)
+ a := NewAntiquary(ctx, nil, preState, vt, &clparams.MainnetBeaconConfig, datadir.New("/tmp"), nil, db, nil, nil, reader, sn, log.New(), true, true, true, false, nil)
require.NoError(t, a.IncrementBeaconState(ctx, blocks[len(blocks)-1].Block.Slot+33))
}
+func TestStateAntiquaryElectra(t *testing.T) {
+ blocks, preState, postState := tests.GetElectraRandom()
+ runTest(t, blocks, preState, postState)
+}
+
func TestStateAntiquaryCapella(t *testing.T) {
blocks, preState, postState := tests.GetCapellaRandom()
runTest(t, blocks, preState, postState)
diff --git a/cl/antiquary/tests/test_data/electra/blocks_0.ssz_snappy b/cl/antiquary/tests/test_data/electra/blocks_0.ssz_snappy
new file mode 100644
index 00000000000..2e2f35ecc02
Binary files /dev/null and b/cl/antiquary/tests/test_data/electra/blocks_0.ssz_snappy differ
diff --git a/cl/antiquary/tests/test_data/electra/blocks_1.ssz_snappy b/cl/antiquary/tests/test_data/electra/blocks_1.ssz_snappy
new file mode 100644
index 00000000000..f50dac5c2ca
Binary files /dev/null and b/cl/antiquary/tests/test_data/electra/blocks_1.ssz_snappy differ
diff --git a/cl/antiquary/tests/test_data/electra/meta.yaml b/cl/antiquary/tests/test_data/electra/meta.yaml
new file mode 100644
index 00000000000..2521cc1d0e1
--- /dev/null
+++ b/cl/antiquary/tests/test_data/electra/meta.yaml
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:73018ecc96aa42f2d6baef211fb8d504750ad1ab638d94705d3d1b051b4ad71e
+size 34
diff --git a/cl/antiquary/tests/test_data/electra/post.ssz_snappy b/cl/antiquary/tests/test_data/electra/post.ssz_snappy
new file mode 100644
index 00000000000..d8877dc5b18
Binary files /dev/null and b/cl/antiquary/tests/test_data/electra/post.ssz_snappy differ
diff --git a/cl/antiquary/tests/test_data/electra/pre.ssz_snappy b/cl/antiquary/tests/test_data/electra/pre.ssz_snappy
new file mode 100644
index 00000000000..3a4b9c26512
Binary files /dev/null and b/cl/antiquary/tests/test_data/electra/pre.ssz_snappy differ
diff --git a/cl/antiquary/tests/tests.go b/cl/antiquary/tests/tests.go
index 454e04209bf..272c001ff49 100644
--- a/cl/antiquary/tests/tests.go
+++ b/cl/antiquary/tests/tests.go
@@ -28,12 +28,23 @@ import (
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/cltypes"
"github.com/erigontech/erigon/cl/persistence/beacon_indicies"
- state_accessors "github.com/erigontech/erigon/cl/persistence/state"
"github.com/erigontech/erigon/cl/phase1/core/state"
"github.com/erigontech/erigon/cl/utils"
"github.com/stretchr/testify/require"
)
+//go:embed test_data/electra/blocks_0.ssz_snappy
+var electra_blocks_0_ssz_snappy []byte
+
+//go:embed test_data/electra/blocks_1.ssz_snappy
+var electra_blocks_1_ssz_snappy []byte
+
+//go:embed test_data/electra/pre.ssz_snappy
+var electra_pre_state_ssz_snappy []byte
+
+//go:embed test_data/electra/post.ssz_snappy
+var electra_post_state_ssz_snappy []byte
+
//go:embed test_data/capella/blocks_0.ssz_snappy
var capella_blocks_0_ssz_snappy []byte
@@ -122,12 +133,35 @@ func LoadChain(blocks []*cltypes.SignedBeaconBlock, s *state.CachingBeaconState,
require.NoError(t, beacon_indicies.WriteBeaconBlockAndIndicies(context.Background(), tx, block, true))
require.NoError(t, beacon_indicies.WriteHighestFinalized(tx, block.Block.Slot+64))
}
- require.NoError(t, state_accessors.InitializeStaticTables(tx, s))
require.NoError(t, tx.Commit())
return m
}
+func GetElectraRandom() ([]*cltypes.SignedBeaconBlock, *state.CachingBeaconState, *state.CachingBeaconState) {
+ block1 := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig, clparams.ElectraVersion)
+ block2 := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig, clparams.ElectraVersion)
+
+ // Lets do te
+ if err := utils.DecodeSSZSnappy(block1, electra_blocks_0_ssz_snappy, int(clparams.ElectraVersion)); err != nil {
+ panic(err)
+ }
+ if err := utils.DecodeSSZSnappy(block2, electra_blocks_1_ssz_snappy, int(clparams.ElectraVersion)); err != nil {
+ panic(err)
+ }
+
+ preState := state.New(&clparams.MainnetBeaconConfig)
+ if err := utils.DecodeSSZSnappy(preState, electra_pre_state_ssz_snappy, int(clparams.ElectraVersion)); err != nil {
+ panic(err)
+
+ }
+ postState := state.New(&clparams.MainnetBeaconConfig)
+ if err := utils.DecodeSSZSnappy(postState, electra_post_state_ssz_snappy, int(clparams.ElectraVersion)); err != nil {
+ panic(err)
+ }
+ return []*cltypes.SignedBeaconBlock{block1, block2}, preState, postState
+}
+
func GetCapellaRandom() ([]*cltypes.SignedBeaconBlock, *state.CachingBeaconState, *state.CachingBeaconState) {
block1 := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig, clparams.CapellaVersion)
block2 := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig, clparams.CapellaVersion)
diff --git a/cl/beacon/handler/attestation_rewards.go b/cl/beacon/handler/attestation_rewards.go
index 2c175c9f4c1..1ab76118e8b 100644
--- a/cl/beacon/handler/attestation_rewards.go
+++ b/cl/beacon/handler/attestation_rewards.go
@@ -88,7 +88,7 @@ func (a *ApiHandler) PostEthV1BeaconRewardsAttestations(w http.ResponseWriter, r
}
}
- filterIndicies, err := parseQueryValidatorIndicies(tx, req)
+ filterIndicies, err := parseQueryValidatorIndicies(a.syncedData, req)
if err != nil {
return nil, err
}
diff --git a/cl/beacon/handler/block_production.go b/cl/beacon/handler/block_production.go
index 8dac0adeeb4..750ae290b12 100644
--- a/cl/beacon/handler/block_production.go
+++ b/cl/beacon/handler/block_production.go
@@ -265,6 +265,7 @@ func (a *ApiHandler) GetEthV3ValidatorBlock(
)
}
+ log.Debug("[Beacon API] Producing block", "slot", targetSlot)
// builder boost factor controls block choice between local execution node or builder
var builderBoostFactor uint64
builderBoostFactorStr := r.URL.Query().Get("builder_boost_factor")
@@ -285,6 +286,8 @@ func (a *ApiHandler) GetEthV3ValidatorBlock(
errors.New("node is syncing"),
)
}
+
+ start := time.Now()
sourceBlock, err := a.blockReader.ReadBlockByRoot(ctx, tx, baseBlockRoot)
if err != nil {
log.Warn("Failed to get source block", "err", err, "root", baseBlockRoot)
@@ -296,10 +299,13 @@ func (a *ApiHandler) GetEthV3ValidatorBlock(
fmt.Errorf("block not found %x", baseBlockRoot),
)
}
+
+ // make a simple copy to the current head state
baseState, err := a.forkchoiceStore.GetStateAtBlockRoot(
baseBlockRoot,
true,
) // we start the block production from this state
+
if err != nil {
return nil, err
}
@@ -312,22 +318,27 @@ func (a *ApiHandler) GetEthV3ValidatorBlock(
if err := transition.DefaultMachine.ProcessSlots(baseState, targetSlot); err != nil {
return nil, err
}
+ log.Info("[Beacon API] Found BeaconState object for block production", "slot", targetSlot, "duration", time.Since(start))
block, err := a.produceBlock(ctx, builderBoostFactor, sourceBlock.Block, baseState, targetSlot, randaoReveal, graffiti)
if err != nil {
log.Warn("Failed to produce block", "err", err, "slot", targetSlot)
return nil, err
}
+ startConsensusProcessing := time.Now()
// do state transition
if err := machine.ProcessBlock(transition.DefaultMachine, baseState, block.ToGeneric()); err != nil {
log.Warn("Failed to process execution block", "err", err, "slot", targetSlot)
return nil, err
}
+ log.Info("[Beacon API] Built block consensus-state", "slot", targetSlot, "duration", time.Since(startConsensusProcessing))
+ startConsensusProcessing = time.Now()
block.StateRoot, err = baseState.HashSSZ()
if err != nil {
log.Warn("Failed to get state root", "err", err)
return nil, err
}
+ log.Info("[Beacon API] Computed state root while producing slot", "slot", targetSlot, "duration", time.Since(startConsensusProcessing))
log.Info("BlockProduction: Block produced",
"proposerIndex", block.ProposerIndex,
@@ -336,6 +347,7 @@ func (a *ApiHandler) GetEthV3ValidatorBlock(
"execution_value", block.GetExecutionValue().Uint64(),
"version", block.Version(),
"blinded", block.IsBlinded(),
+ "took", time.Since(start),
)
// todo: consensusValue
@@ -380,6 +392,10 @@ func (a *ApiHandler) produceBlock(
kzgProofs []libcommon.Bytes48
)
go func() {
+ start := time.Now()
+ defer func() {
+ a.logger.Debug("Produced BeaconBody", "slot", targetSlot, "duration", time.Since(start))
+ }()
defer wg.Done()
beaconBody, localExecValue, localErr = a.produceBeaconBody(ctx, 3, baseBlock, baseState, targetSlot, randaoReveal, graffiti)
// collect blobs
@@ -407,6 +423,10 @@ func (a *ApiHandler) produceBlock(
builderErr error
)
go func() {
+ start := time.Now()
+ defer func() {
+ a.logger.Debug("MevBoost", "slot", targetSlot, "duration", time.Since(start))
+ }()
defer wg.Done()
if a.routerCfg.Builder && a.builderClient != nil {
builderHeader, builderErr = a.getBuilderPayload(ctx, baseBlock, baseState, targetSlot)
@@ -1161,6 +1181,24 @@ func (a *ApiHandler) storeBlockAndBlobs(
if _, err := a.engine.ForkChoiceUpdate(ctx, a.forkchoiceStore.GetEth1Hash(finalizedBlockRoot), a.forkchoiceStore.GetEth1Hash(blockRoot), nil); err != nil {
return err
}
+ headState, err := a.forkchoiceStore.GetStateAtBlockRoot(blockRoot, false)
+ if err != nil {
+ return err
+ }
+ if headState == nil {
+ return errors.New("failed to get head state")
+ }
+
+ if err := a.indiciesDB.View(ctx, func(tx kv.Tx) error {
+ _, err := a.attestationProducer.ProduceAndCacheAttestationData(tx, headState, blockRoot, block.Block.Slot, 0)
+ return err
+ }); err != nil {
+ return err
+ }
+ if err := a.syncedData.OnHeadState(headState); err != nil {
+ return fmt.Errorf("failed to update synced data: %w", err)
+ }
+
return nil
}
diff --git a/cl/beacon/handler/duties_attester.go b/cl/beacon/handler/duties_attester.go
index 31040bdbab2..fcf24ff7f6c 100644
--- a/cl/beacon/handler/duties_attester.go
+++ b/cl/beacon/handler/duties_attester.go
@@ -194,7 +194,8 @@ func (a *ApiHandler) getAttesterDuties(w http.ResponseWriter, r *http.Request) (
if _, ok := idxSet[int(idx)]; !ok {
continue
}
- publicKey, err := state_accessors.ReadPublicKeyByIndex(tx, idx)
+
+ publicKey, err := a.syncedData.ValidatorPublicKeyByIndex(int(idx))
if err != nil {
return nil, err
}
diff --git a/cl/beacon/handler/duties_proposer.go b/cl/beacon/handler/duties_proposer.go
index 24c3399d6a9..4aefcd81186 100644
--- a/cl/beacon/handler/duties_proposer.go
+++ b/cl/beacon/handler/duties_proposer.go
@@ -67,7 +67,7 @@ func (a *ApiHandler) getDutiesProposer(w http.ResponseWriter, r *http.Request) (
duties := make([]proposerDuties, len(indicies))
for i, validatorIndex := range indicies {
var pk libcommon.Bytes48
- pk, err := state_accessors.ReadPublicKeyByIndex(tx, validatorIndex)
+ pk, err := a.syncedData.ValidatorPublicKeyByIndex(int(validatorIndex))
if err != nil {
return nil, err
}
diff --git a/cl/beacon/handler/duties_sync.go b/cl/beacon/handler/duties_sync.go
index bc4e7cc082a..9a6443d978a 100644
--- a/cl/beacon/handler/duties_sync.go
+++ b/cl/beacon/handler/duties_sync.go
@@ -103,7 +103,7 @@ func (a *ApiHandler) getSyncDuties(w http.ResponseWriter, r *http.Request) (*bea
// Now we have the sync committee, we can initialize our response set
dutiesSet := map[uint64]*syncDutyResponse{}
for _, idx := range idxs {
- publicKey, err := state_accessors.ReadPublicKeyByIndex(tx, idx)
+ publicKey, err := a.syncedData.ValidatorPublicKeyByIndex(int(idx))
if err != nil {
return nil, err
}
@@ -117,12 +117,9 @@ func (a *ApiHandler) getSyncDuties(w http.ResponseWriter, r *http.Request) (*bea
}
// Now we can iterate over the sync committee and fill the response
for idx, committeeParticipantPublicKey := range syncCommittee.GetCommittee() {
- committeeParticipantIndex, ok, err := state_accessors.ReadValidatorIndexByPublicKey(tx, committeeParticipantPublicKey)
+ committeeParticipantIndex, _, err := a.syncedData.ValidatorIndexByPublicKey(committeeParticipantPublicKey)
if err != nil {
- return nil, err
- }
- if !ok {
- return nil, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("could not find validator with public key %x", committeeParticipantPublicKey))
+ return nil, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("could not find validator with public key %x: %s", committeeParticipantPublicKey, err))
}
if _, ok := dutiesSet[committeeParticipantIndex]; !ok {
continue
diff --git a/cl/beacon/handler/lighthouse.go b/cl/beacon/handler/lighthouse.go
index f2e978f5e56..4a6dc1a7f6f 100644
--- a/cl/beacon/handler/lighthouse.go
+++ b/cl/beacon/handler/lighthouse.go
@@ -228,7 +228,7 @@ func (a *ApiHandler) GetLighthouseValidatorInclusion(w http.ResponseWriter, r *h
return nil, beaconhttp.NewEndpointError(http.StatusBadRequest, err)
}
- validatorIndex, err := parseQueryValidatorIndex(tx, validatorId)
+ validatorIndex, err := parseQueryValidatorIndex(a.syncedData, validatorId)
if err != nil {
return nil, err
}
diff --git a/cl/beacon/handler/rewards.go b/cl/beacon/handler/rewards.go
index 6a302207020..72488120499 100644
--- a/cl/beacon/handler/rewards.go
+++ b/cl/beacon/handler/rewards.go
@@ -19,6 +19,7 @@ package handler
import (
"encoding/json"
"errors"
+ "fmt"
"io"
"net/http"
"sort"
@@ -85,7 +86,7 @@ func (a *ApiHandler) GetEthV1BeaconRewardsBlocks(w http.ResponseWriter, r *http.
defer snRoTx.Close()
stateGetter := state_accessors.GetValFnTxAndSnapshot(tx, snRoTx)
- slotData, err := state_accessors.ReadSlotData(stateGetter, slot)
+ slotData, err := state_accessors.ReadSlotData(stateGetter, slot, a.beaconChainCfg)
if err != nil {
return nil, err
}
@@ -128,7 +129,7 @@ func (a *ApiHandler) PostEthV1BeaconRewardsSyncCommittees(w http.ResponseWriter,
return nil, beaconhttp.NewEndpointError(http.StatusBadRequest, err)
}
}
- filterIndicies, err := parseQueryValidatorIndicies(tx, req)
+ filterIndicies, err := parseQueryValidatorIndicies(a.syncedData, req)
if err != nil {
return nil, err
}
@@ -217,12 +218,9 @@ func (a *ApiHandler) PostEthV1BeaconRewardsSyncCommittees(w http.ResponseWriter,
participantReward := int64(a.syncParticipantReward(totalActiveBalance))
for committeeIdx, v := range committee {
- idx, ok, err := state_accessors.ReadValidatorIndexByPublicKey(tx, v)
+ idx, _, err := a.syncedData.ValidatorIndexByPublicKey(v)
if err != nil {
- return nil, err
- }
- if !ok {
- return nil, beaconhttp.NewEndpointError(http.StatusNotFound, errors.New("sync committee public key not found"))
+ return nil, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("sync committee public key not found: %s", err))
}
if len(filterIndiciesSet) > 0 {
if _, ok := filterIndiciesSet[idx]; !ok {
diff --git a/cl/beacon/handler/rewards_test.go b/cl/beacon/handler/rewards_test.go
index 07bc6bbe769..3dc8d78b85c 100644
--- a/cl/beacon/handler/rewards_test.go
+++ b/cl/beacon/handler/rewards_test.go
@@ -89,7 +89,7 @@ func TestGetBlockRewards(t *testing.T) {
}
func TestPostSyncCommitteeRewards(t *testing.T) {
- _, blocks, _, _, _, handler, _, _, fcu, _ := setupTestingHandler(t, clparams.BellatrixVersion, log.Root(), false)
+ _, blocks, _, _, _, handler, _, _, fcu, _ := setupTestingHandler(t, clparams.BellatrixVersion, log.Root(), true)
var err error
fcu.HeadVal, err = blocks[len(blocks)-1].Block.HashSSZ()
require.NoError(t, err)
diff --git a/cl/beacon/handler/states.go b/cl/beacon/handler/states.go
index e781433c74a..b63deedd626 100644
--- a/cl/beacon/handler/states.go
+++ b/cl/beacon/handler/states.go
@@ -365,12 +365,9 @@ func (a *ApiHandler) getSyncCommittees(w http.ResponseWriter, r *http.Request) (
}
for i, publicKey := range committee {
// get the validator index of the committee
- validatorIndex, ok, err := state_accessors.ReadValidatorIndexByPublicKey(tx, publicKey)
+ validatorIndex, _, err := a.syncedData.ValidatorIndexByPublicKey(publicKey)
if err != nil {
- return nil, err
- }
- if !ok {
- return nil, fmt.Errorf("could not read validator index: %x", publicKey)
+ return nil, fmt.Errorf("could not read validator index: %x. %s", publicKey, err)
}
idx := strconv.FormatInt(int64(validatorIndex), 10)
response.Validators[i] = idx
diff --git a/cl/beacon/handler/states_test.go b/cl/beacon/handler/states_test.go
index 5222c291fa0..42eaa00dba7 100644
--- a/cl/beacon/handler/states_test.go
+++ b/cl/beacon/handler/states_test.go
@@ -320,7 +320,7 @@ func TestGetStateFullForkchoice(t *testing.T) {
func TestGetStateSyncCommittees(t *testing.T) {
// setupTestingHandler(t, clparams.Phase0Version)
- _, blocks, _, _, postState, handler, _, _, fcu, _ := setupTestingHandler(t, clparams.BellatrixVersion, log.Root(), false)
+ _, blocks, _, _, postState, handler, _, _, fcu, _ := setupTestingHandler(t, clparams.BellatrixVersion, log.Root(), true)
postRoot, err := postState.HashSSZ()
require.NoError(t, err)
@@ -385,7 +385,7 @@ func TestGetStateSyncCommittees(t *testing.T) {
func TestGetStateSyncCommitteesHistorical(t *testing.T) {
// setupTestingHandler(t, clparams.Phase0Version)
- _, blocks, _, _, postState, handler, _, _, fcu, _ := setupTestingHandler(t, clparams.BellatrixVersion, log.Root(), false)
+ _, blocks, _, _, postState, handler, _, _, fcu, _ := setupTestingHandler(t, clparams.BellatrixVersion, log.Root(), true)
postRoot, err := postState.HashSSZ()
require.NoError(t, err)
diff --git a/cl/beacon/handler/subscription.go b/cl/beacon/handler/subscription.go
index 63e187fd79c..caa4041f32c 100644
--- a/cl/beacon/handler/subscription.go
+++ b/cl/beacon/handler/subscription.go
@@ -84,6 +84,7 @@ func (a *ApiHandler) PostEthV1ValidatorSyncCommitteeSubscriptions(w http.Respons
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
+ //cn()
}
// subscribe to subnets
diff --git a/cl/beacon/handler/utils_test.go b/cl/beacon/handler/utils_test.go
index 5b3c57b2d79..16e403388c0 100644
--- a/cl/beacon/handler/utils_test.go
+++ b/cl/beacon/handler/utils_test.go
@@ -69,27 +69,27 @@ func setupTestingHandler(t *testing.T, v clparams.StateVersion, logger log.Logge
fcu = mock_services2.NewForkChoiceStorageMock(t)
db = memdb.NewTestDB(t, kv.ChainDB)
blobDb := memdb.NewTestDB(t, kv.ChainDB)
- var reader *tests.MockBlockReader
- reader = tests.LoadChain(blocks, postState, db, t)
+ reader := tests.LoadChain(blocks, postState, db, t)
firstBlockRoot, _ := blocks[0].Block.HashSSZ()
firstBlockHeader := blocks[0].SignedBeaconBlockHeader()
bcfg.InitializeForkSchedule()
+ if useRealSyncDataMgr {
+ syncedData = synced_data.NewSyncedDataManager(&bcfg, true)
+ syncedData.OnHeadState(postState)
+ } else {
+ syncedData = sync_mock_services.NewMockSyncedData(ctrl)
+ }
ctx := context.Background()
vt := state_accessors.NewStaticValidatorTable()
- a := antiquary.NewAntiquary(ctx, nil, preState, vt, &bcfg, datadir.New("/tmp"), nil, db, nil, nil, reader, logger, true, true, false, false, nil)
+ a := antiquary.NewAntiquary(ctx, nil, preState, vt, &bcfg, datadir.New("/tmp"), nil, db, nil, nil, reader, syncedData, logger, true, true, false, false, nil)
require.NoError(t, a.IncrementBeaconState(ctx, blocks[len(blocks)-1].Block.Slot+33))
// historical states reader below
- statesReader := historical_states_reader.NewHistoricalStatesReader(&bcfg, reader, vt, preState, nil)
+ statesReader := historical_states_reader.NewHistoricalStatesReader(&bcfg, reader, vt, preState, nil, syncedData)
opPool = pool.NewOperationsPool(&bcfg)
fcu.Pool = opPool
- if useRealSyncDataMgr {
- syncedData = synced_data.NewSyncedDataManager(&bcfg, true)
- } else {
- syncedData = sync_mock_services.NewMockSyncedData(ctrl)
- }
genesis, err := initial_state.GetGenesisState(clparams.MainnetNetwork)
require.NoError(t, err)
ethClock := eth_clock.NewEthereumClock(genesis.GenesisTime(), genesis.GenesisValidatorsRoot(), &bcfg)
diff --git a/cl/beacon/handler/validators.go b/cl/beacon/handler/validators.go
index e9952d006f1..276e0f7d9f1 100644
--- a/cl/beacon/handler/validators.go
+++ b/cl/beacon/handler/validators.go
@@ -35,6 +35,7 @@ import (
"github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/cl/beacon/beaconhttp"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/cltypes/solid"
"github.com/erigontech/erigon/cl/persistence/beacon_indicies"
state_accessors "github.com/erigontech/erigon/cl/persistence/state"
@@ -173,16 +174,10 @@ func (s validatorStatus) String() string {
}
}
-const maxValidatorsLookupFilter = 128
-
func parseStatuses(s []string) ([]validatorStatus, error) {
seenAlready := make(map[validatorStatus]struct{})
statuses := make([]validatorStatus, 0, len(s))
- if len(s) > maxValidatorsLookupFilter {
- return nil, beaconhttp.NewEndpointError(http.StatusBadRequest, errors.New("too many statuses requested"))
- }
-
for _, status := range s {
s, err := validatorStatusFromString(status)
if err != nil {
@@ -247,10 +242,6 @@ func (a *ApiHandler) GetEthV1BeaconStatesValidators(w http.ResponseWriter, r *ht
return
}
- if len(validatorIds) > maxValidatorsLookupFilter {
- http.Error(w, errors.New("too many validators requested").Error(), http.StatusBadRequest)
- return
- }
a.writeValidatorsResponse(w, r, tx, blockId, blockRoot, validatorIds, queryFilters)
}
@@ -287,11 +278,6 @@ func (a *ApiHandler) PostEthV1BeaconStatesValidators(w http.ResponseWriter, r *h
return
}
- if len(req.Ids) > maxValidatorsLookupFilter {
- http.Error(w, errors.New("too many validators requested").Error(), http.StatusBadRequest)
- return
- }
-
a.writeValidatorsResponse(w, r, tx, blockId, blockRoot, req.Ids, req.Statuses)
}
@@ -305,7 +291,7 @@ func (a *ApiHandler) writeValidatorsResponse(
queryFilters []string,
) {
isOptimistic := a.forkchoiceStore.IsRootOptimistic(blockRoot)
- filterIndicies, err := parseQueryValidatorIndicies(tx, validatorIds)
+ filterIndicies, err := parseQueryValidatorIndicies(a.syncedData, validatorIds)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@@ -381,7 +367,7 @@ func (a *ApiHandler) writeValidatorsResponse(
responseValidators(w, filterIndicies, statusFilters, stateEpoch, balances, validators, *slot <= a.forkchoiceStore.FinalizedSlot(), isOptimistic)
}
-func parseQueryValidatorIndex(tx kv.Tx, id string) (uint64, error) {
+func parseQueryValidatorIndex(syncedData synced_data.SyncedData, id string) (uint64, error) {
isPublicKey, err := checkValidValidatorId(id)
if err != nil {
return 0, err
@@ -391,20 +377,13 @@ func parseQueryValidatorIndex(tx kv.Tx, id string) (uint64, error) {
if err := b48.UnmarshalText([]byte(id)); err != nil {
return 0, beaconhttp.NewEndpointError(http.StatusBadRequest, err)
}
- has, err := tx.Has(kv.InvertedValidatorPublicKeys, b48[:])
+ idx, has, err := syncedData.ValidatorIndexByPublicKey(b48)
if err != nil {
- return 0, err
+ return 0, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("validator not found: %s", err))
}
if !has {
return math.MaxUint64, nil
}
- idx, ok, err := state_accessors.ReadValidatorIndexByPublicKey(tx, b48)
- if err != nil {
- return 0, err
- }
- if !ok {
- return 0, beaconhttp.NewEndpointError(http.StatusNotFound, errors.New("validator not found"))
- }
return idx, nil
}
idx, err := strconv.ParseUint(id, 10, 64)
@@ -415,11 +394,11 @@ func parseQueryValidatorIndex(tx kv.Tx, id string) (uint64, error) {
}
-func parseQueryValidatorIndicies(tx kv.Tx, ids []string) ([]uint64, error) {
+func parseQueryValidatorIndicies(syncedData synced_data.SyncedData, ids []string) ([]uint64, error) {
filterIndicies := make([]uint64, 0, len(ids))
for _, id := range ids {
- idx, err := parseQueryValidatorIndex(tx, id)
+ idx, err := parseQueryValidatorIndex(syncedData, id)
if err != nil {
return nil, err
}
@@ -454,7 +433,7 @@ func (a *ApiHandler) GetEthV1BeaconStatesValidator(w http.ResponseWriter, r *htt
return nil, beaconhttp.NewEndpointError(http.StatusBadRequest, err)
}
- validatorIndex, err := parseQueryValidatorIndex(tx, validatorId)
+ validatorIndex, err := parseQueryValidatorIndex(a.syncedData, validatorId)
if err != nil {
return nil, err
}
@@ -542,11 +521,6 @@ func (a *ApiHandler) PostEthV1BeaconValidatorsBalances(w http.ResponseWriter, r
return
}
- if len(validatorIds) > maxValidatorsLookupFilter {
- http.Error(w, errors.New("too many validators requested").Error(), http.StatusBadRequest)
- return
- }
-
a.getValidatorBalances(r.Context(), w, blockId, validatorIds)
}
@@ -564,10 +538,6 @@ func (a *ApiHandler) GetEthV1BeaconValidatorsBalances(w http.ResponseWriter, r *
return
}
- if len(validatorIds) > maxValidatorsLookupFilter {
- http.Error(w, errors.New("too many validators requested").Error(), http.StatusBadRequest)
- return
- }
a.getValidatorBalances(r.Context(), w, blockId, validatorIds)
}
@@ -585,7 +555,7 @@ func (a *ApiHandler) getValidatorBalances(ctx context.Context, w http.ResponseWr
return
}
- filterIndicies, err := parseQueryValidatorIndicies(tx, validatorIds)
+ filterIndicies, err := parseQueryValidatorIndicies(a.syncedData, validatorIds)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
diff --git a/cl/beacon/synced_data/interface.go b/cl/beacon/synced_data/interface.go
index 0cb84905d2a..304ac4be2a7 100644
--- a/cl/beacon/synced_data/interface.go
+++ b/cl/beacon/synced_data/interface.go
@@ -18,6 +18,7 @@ package synced_data
import (
"github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon/cl/cltypes"
"github.com/erigontech/erigon/cl/phase1/core/state"
)
@@ -33,4 +34,8 @@ type SyncedData interface {
HeadSlot() uint64
HeadRoot() common.Hash
CommitteeCount(epoch uint64) uint64
+ ValidatorPublicKeyByIndex(index int) (common.Bytes48, error)
+ ValidatorIndexByPublicKey(pubkey common.Bytes48) (uint64, bool, error)
+ HistoricalRootElementAtIndex(index int) (common.Hash, error)
+ HistoricalSummaryElementAtIndex(index int) (*cltypes.HistoricalSummary, error)
}
diff --git a/cl/beacon/synced_data/mock_services/synced_data_mock.go b/cl/beacon/synced_data/mock_services/synced_data_mock.go
index 5a37152a15b..6eebd97dbf0 100644
--- a/cl/beacon/synced_data/mock_services/synced_data_mock.go
+++ b/cl/beacon/synced_data/mock_services/synced_data_mock.go
@@ -14,6 +14,7 @@ import (
common "github.com/erigontech/erigon-lib/common"
synced_data "github.com/erigontech/erigon/cl/beacon/synced_data"
+ cltypes "github.com/erigontech/erigon/cl/cltypes"
state "github.com/erigontech/erigon/cl/phase1/core/state"
gomock "go.uber.org/mock/gomock"
)
@@ -22,7 +23,6 @@ import (
type MockSyncedData struct {
ctrl *gomock.Controller
recorder *MockSyncedDataMockRecorder
- isgomock struct{}
}
// MockSyncedDataMockRecorder is the mock recorder for MockSyncedData.
@@ -43,17 +43,17 @@ func (m *MockSyncedData) EXPECT() *MockSyncedDataMockRecorder {
}
// CommitteeCount mocks base method.
-func (m *MockSyncedData) CommitteeCount(epoch uint64) uint64 {
+func (m *MockSyncedData) CommitteeCount(arg0 uint64) uint64 {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "CommitteeCount", epoch)
+ ret := m.ctrl.Call(m, "CommitteeCount", arg0)
ret0, _ := ret[0].(uint64)
return ret0
}
// CommitteeCount indicates an expected call of CommitteeCount.
-func (mr *MockSyncedDataMockRecorder) CommitteeCount(epoch any) *MockSyncedDataCommitteeCountCall {
+func (mr *MockSyncedDataMockRecorder) CommitteeCount(arg0 any) *MockSyncedDataCommitteeCountCall {
mr.mock.ctrl.T.Helper()
- call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitteeCount", reflect.TypeOf((*MockSyncedData)(nil).CommitteeCount), epoch)
+ call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitteeCount", reflect.TypeOf((*MockSyncedData)(nil).CommitteeCount), arg0)
return &MockSyncedDataCommitteeCountCall{Call: call}
}
@@ -156,18 +156,96 @@ func (c *MockSyncedDataHeadSlotCall) DoAndReturn(f func() uint64) *MockSyncedDat
return c
}
+// HistoricalRootElementAtIndex mocks base method.
+func (m *MockSyncedData) HistoricalRootElementAtIndex(arg0 int) (common.Hash, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "HistoricalRootElementAtIndex", arg0)
+ ret0, _ := ret[0].(common.Hash)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// HistoricalRootElementAtIndex indicates an expected call of HistoricalRootElementAtIndex.
+func (mr *MockSyncedDataMockRecorder) HistoricalRootElementAtIndex(arg0 any) *MockSyncedDataHistoricalRootElementAtIndexCall {
+ mr.mock.ctrl.T.Helper()
+ call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HistoricalRootElementAtIndex", reflect.TypeOf((*MockSyncedData)(nil).HistoricalRootElementAtIndex), arg0)
+ return &MockSyncedDataHistoricalRootElementAtIndexCall{Call: call}
+}
+
+// MockSyncedDataHistoricalRootElementAtIndexCall wrap *gomock.Call
+type MockSyncedDataHistoricalRootElementAtIndexCall struct {
+ *gomock.Call
+}
+
+// Return rewrite *gomock.Call.Return
+func (c *MockSyncedDataHistoricalRootElementAtIndexCall) Return(arg0 common.Hash, arg1 error) *MockSyncedDataHistoricalRootElementAtIndexCall {
+ c.Call = c.Call.Return(arg0, arg1)
+ return c
+}
+
+// Do rewrite *gomock.Call.Do
+func (c *MockSyncedDataHistoricalRootElementAtIndexCall) Do(f func(int) (common.Hash, error)) *MockSyncedDataHistoricalRootElementAtIndexCall {
+ c.Call = c.Call.Do(f)
+ return c
+}
+
+// DoAndReturn rewrite *gomock.Call.DoAndReturn
+func (c *MockSyncedDataHistoricalRootElementAtIndexCall) DoAndReturn(f func(int) (common.Hash, error)) *MockSyncedDataHistoricalRootElementAtIndexCall {
+ c.Call = c.Call.DoAndReturn(f)
+ return c
+}
+
+// HistoricalSummaryElementAtIndex mocks base method.
+func (m *MockSyncedData) HistoricalSummaryElementAtIndex(arg0 int) (*cltypes.HistoricalSummary, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "HistoricalSummaryElementAtIndex", arg0)
+ ret0, _ := ret[0].(*cltypes.HistoricalSummary)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// HistoricalSummaryElementAtIndex indicates an expected call of HistoricalSummaryElementAtIndex.
+func (mr *MockSyncedDataMockRecorder) HistoricalSummaryElementAtIndex(arg0 any) *MockSyncedDataHistoricalSummaryElementAtIndexCall {
+ mr.mock.ctrl.T.Helper()
+ call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HistoricalSummaryElementAtIndex", reflect.TypeOf((*MockSyncedData)(nil).HistoricalSummaryElementAtIndex), arg0)
+ return &MockSyncedDataHistoricalSummaryElementAtIndexCall{Call: call}
+}
+
+// MockSyncedDataHistoricalSummaryElementAtIndexCall wrap *gomock.Call
+type MockSyncedDataHistoricalSummaryElementAtIndexCall struct {
+ *gomock.Call
+}
+
+// Return rewrite *gomock.Call.Return
+func (c *MockSyncedDataHistoricalSummaryElementAtIndexCall) Return(arg0 *cltypes.HistoricalSummary, arg1 error) *MockSyncedDataHistoricalSummaryElementAtIndexCall {
+ c.Call = c.Call.Return(arg0, arg1)
+ return c
+}
+
+// Do rewrite *gomock.Call.Do
+func (c *MockSyncedDataHistoricalSummaryElementAtIndexCall) Do(f func(int) (*cltypes.HistoricalSummary, error)) *MockSyncedDataHistoricalSummaryElementAtIndexCall {
+ c.Call = c.Call.Do(f)
+ return c
+}
+
+// DoAndReturn rewrite *gomock.Call.DoAndReturn
+func (c *MockSyncedDataHistoricalSummaryElementAtIndexCall) DoAndReturn(f func(int) (*cltypes.HistoricalSummary, error)) *MockSyncedDataHistoricalSummaryElementAtIndexCall {
+ c.Call = c.Call.DoAndReturn(f)
+ return c
+}
+
// OnHeadState mocks base method.
-func (m *MockSyncedData) OnHeadState(newState *state.CachingBeaconState) error {
+func (m *MockSyncedData) OnHeadState(arg0 *state.CachingBeaconState) error {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "OnHeadState", newState)
+ ret := m.ctrl.Call(m, "OnHeadState", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// OnHeadState indicates an expected call of OnHeadState.
-func (mr *MockSyncedDataMockRecorder) OnHeadState(newState any) *MockSyncedDataOnHeadStateCall {
+func (mr *MockSyncedDataMockRecorder) OnHeadState(arg0 any) *MockSyncedDataOnHeadStateCall {
mr.mock.ctrl.T.Helper()
- call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnHeadState", reflect.TypeOf((*MockSyncedData)(nil).OnHeadState), newState)
+ call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnHeadState", reflect.TypeOf((*MockSyncedData)(nil).OnHeadState), arg0)
return &MockSyncedDataOnHeadStateCall{Call: call}
}
@@ -268,18 +346,97 @@ func (c *MockSyncedDataUnsetHeadStateCall) DoAndReturn(f func()) *MockSyncedData
return c
}
+// ValidatorIndexByPublicKey mocks base method.
+func (m *MockSyncedData) ValidatorIndexByPublicKey(arg0 common.Bytes48) (uint64, bool, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ValidatorIndexByPublicKey", arg0)
+ ret0, _ := ret[0].(uint64)
+ ret1, _ := ret[1].(bool)
+ ret2, _ := ret[2].(error)
+ return ret0, ret1, ret2
+}
+
+// ValidatorIndexByPublicKey indicates an expected call of ValidatorIndexByPublicKey.
+func (mr *MockSyncedDataMockRecorder) ValidatorIndexByPublicKey(arg0 any) *MockSyncedDataValidatorIndexByPublicKeyCall {
+ mr.mock.ctrl.T.Helper()
+ call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorIndexByPublicKey", reflect.TypeOf((*MockSyncedData)(nil).ValidatorIndexByPublicKey), arg0)
+ return &MockSyncedDataValidatorIndexByPublicKeyCall{Call: call}
+}
+
+// MockSyncedDataValidatorIndexByPublicKeyCall wrap *gomock.Call
+type MockSyncedDataValidatorIndexByPublicKeyCall struct {
+ *gomock.Call
+}
+
+// Return rewrite *gomock.Call.Return
+func (c *MockSyncedDataValidatorIndexByPublicKeyCall) Return(arg0 uint64, arg1 bool, arg2 error) *MockSyncedDataValidatorIndexByPublicKeyCall {
+ c.Call = c.Call.Return(arg0, arg1, arg2)
+ return c
+}
+
+// Do rewrite *gomock.Call.Do
+func (c *MockSyncedDataValidatorIndexByPublicKeyCall) Do(f func(common.Bytes48) (uint64, bool, error)) *MockSyncedDataValidatorIndexByPublicKeyCall {
+ c.Call = c.Call.Do(f)
+ return c
+}
+
+// DoAndReturn rewrite *gomock.Call.DoAndReturn
+func (c *MockSyncedDataValidatorIndexByPublicKeyCall) DoAndReturn(f func(common.Bytes48) (uint64, bool, error)) *MockSyncedDataValidatorIndexByPublicKeyCall {
+ c.Call = c.Call.DoAndReturn(f)
+ return c
+}
+
+// ValidatorPublicKeyByIndex mocks base method.
+func (m *MockSyncedData) ValidatorPublicKeyByIndex(arg0 int) (common.Bytes48, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ValidatorPublicKeyByIndex", arg0)
+ ret0, _ := ret[0].(common.Bytes48)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// ValidatorPublicKeyByIndex indicates an expected call of ValidatorPublicKeyByIndex.
+func (mr *MockSyncedDataMockRecorder) ValidatorPublicKeyByIndex(arg0 any) *MockSyncedDataValidatorPublicKeyByIndexCall {
+ mr.mock.ctrl.T.Helper()
+ call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorPublicKeyByIndex", reflect.TypeOf((*MockSyncedData)(nil).ValidatorPublicKeyByIndex), arg0)
+ return &MockSyncedDataValidatorPublicKeyByIndexCall{Call: call}
+}
+
+// MockSyncedDataValidatorPublicKeyByIndexCall wrap *gomock.Call
+type MockSyncedDataValidatorPublicKeyByIndexCall struct {
+ *gomock.Call
+}
+
+// Return rewrite *gomock.Call.Return
+func (c *MockSyncedDataValidatorPublicKeyByIndexCall) Return(arg0 common.Bytes48, arg1 error) *MockSyncedDataValidatorPublicKeyByIndexCall {
+ c.Call = c.Call.Return(arg0, arg1)
+ return c
+}
+
+// Do rewrite *gomock.Call.Do
+func (c *MockSyncedDataValidatorPublicKeyByIndexCall) Do(f func(int) (common.Bytes48, error)) *MockSyncedDataValidatorPublicKeyByIndexCall {
+ c.Call = c.Call.Do(f)
+ return c
+}
+
+// DoAndReturn rewrite *gomock.Call.DoAndReturn
+func (c *MockSyncedDataValidatorPublicKeyByIndexCall) DoAndReturn(f func(int) (common.Bytes48, error)) *MockSyncedDataValidatorPublicKeyByIndexCall {
+ c.Call = c.Call.DoAndReturn(f)
+ return c
+}
+
// ViewHeadState mocks base method.
-func (m *MockSyncedData) ViewHeadState(fn synced_data.ViewHeadStateFn) error {
+func (m *MockSyncedData) ViewHeadState(arg0 synced_data.ViewHeadStateFn) error {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ViewHeadState", fn)
+ ret := m.ctrl.Call(m, "ViewHeadState", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// ViewHeadState indicates an expected call of ViewHeadState.
-func (mr *MockSyncedDataMockRecorder) ViewHeadState(fn any) *MockSyncedDataViewHeadStateCall {
+func (mr *MockSyncedDataMockRecorder) ViewHeadState(arg0 any) *MockSyncedDataViewHeadStateCall {
mr.mock.ctrl.T.Helper()
- call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewHeadState", reflect.TypeOf((*MockSyncedData)(nil).ViewHeadState), fn)
+ call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewHeadState", reflect.TypeOf((*MockSyncedData)(nil).ViewHeadState), arg0)
return &MockSyncedDataViewHeadStateCall{Call: call}
}
diff --git a/cl/beacon/synced_data/synced_data.go b/cl/beacon/synced_data/synced_data.go
index ec24524eb8f..ef79ac49194 100644
--- a/cl/beacon/synced_data/synced_data.go
+++ b/cl/beacon/synced_data/synced_data.go
@@ -26,6 +26,7 @@ import (
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/dbg"
"github.com/erigontech/erigon/cl/clparams"
+ "github.com/erigontech/erigon/cl/cltypes"
"github.com/erigontech/erigon/cl/phase1/core/state"
)
@@ -44,6 +45,8 @@ type SyncedDataManager struct {
headState *state.CachingBeaconState
+ accessLock sync.RWMutex // lock used for accessing atomic methods
+
mu sync.RWMutex
}
@@ -61,6 +64,8 @@ func (s *SyncedDataManager) OnHeadState(newState *state.CachingBeaconState) (err
s.mu.Lock()
defer s.mu.Unlock()
+ s.accessLock.Lock()
+ defer s.accessLock.Unlock()
var blkRoot common.Hash
@@ -137,7 +142,54 @@ func (s *SyncedDataManager) CommitteeCount(epoch uint64) uint64 {
func (s *SyncedDataManager) UnsetHeadState() {
s.mu.Lock()
defer s.mu.Unlock()
+ s.accessLock.Lock()
+ defer s.accessLock.Unlock()
s.headRoot = atomic.Value{}
s.headSlot.Store(uint64(0))
s.headState = nil
}
+
+func (s *SyncedDataManager) ValidatorPublicKeyByIndex(index int) (common.Bytes48, error) {
+ s.accessLock.RLock()
+ defer s.accessLock.RUnlock()
+ if s.headState == nil {
+ return common.Bytes48{}, ErrNotSynced
+ }
+ return s.headState.ValidatorPublicKey(index)
+}
+
+func (s *SyncedDataManager) ValidatorIndexByPublicKey(pubkey common.Bytes48) (uint64, bool, error) {
+ s.accessLock.RLock()
+ defer s.accessLock.RUnlock()
+ if s.headState == nil {
+ return 0, false, ErrNotSynced
+ }
+ ret, found := s.headState.ValidatorIndexByPubkey(pubkey)
+ return ret, found, nil
+}
+
+func (s *SyncedDataManager) HistoricalRootElementAtIndex(index int) (common.Hash, error) {
+ s.accessLock.RLock()
+ defer s.accessLock.RUnlock()
+ if s.headState == nil {
+ return common.Hash{}, ErrNotSynced
+ }
+ if s.headState.HistoricalRootsLength() <= uint64(index) {
+ return common.Hash{}, errors.New("HistoricalRootElementAtIndex: index out of range")
+ }
+
+ return s.headState.HistoricalRoot(index), nil
+}
+
+func (s *SyncedDataManager) HistoricalSummaryElementAtIndex(index int) (*cltypes.HistoricalSummary, error) {
+ s.accessLock.RLock()
+ defer s.accessLock.RUnlock()
+ if s.headState == nil {
+ return nil, ErrNotSynced
+ }
+ if s.headState.HistoricalSummariesLength() <= uint64(index) {
+ return nil, errors.New("HistoricalSummaryElementAtIndex: index out of range")
+ }
+
+ return s.headState.HistoricalSummary(index), nil
+}
diff --git a/cl/clparams/config.go b/cl/clparams/config.go
index 67d0cb99f91..25aeaeba310 100644
--- a/cl/clparams/config.go
+++ b/cl/clparams/config.go
@@ -105,11 +105,12 @@ const (
)
const (
- MaxDialTimeout = 15 * time.Second
- VersionLength int = 4
- MaxChunkSize uint64 = 1 << 20 // 1 MiB
- ReqTimeout time.Duration = 10 * time.Second
- RespTimeout time.Duration = 15 * time.Second
+ MaxDialTimeout = 15 * time.Second
+ VersionLength int = 4
+ // 15 MiB
+ MaxChunkSize uint64 = 15728640
+ ReqTimeout time.Duration = 10 * time.Second
+ RespTimeout time.Duration = 15 * time.Second
)
const (
@@ -210,8 +211,8 @@ type NetworkConfig struct {
var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig{
MainnetNetwork: {
- GossipMaxSize: 1 << 20, // 1 MiB
- GossipMaxSizeBellatrix: 10485760,
+ GossipMaxSize: 15728640,
+ GossipMaxSizeBellatrix: 15728640,
MaxChunkSize: MaxChunkSize,
AttestationSubnetCount: 64,
AttestationPropagationSlotRange: 32,
@@ -229,9 +230,9 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig
},
SepoliaNetwork: {
- GossipMaxSize: 1 << 20, // 1 MiB
- GossipMaxSizeBellatrix: 10485760,
- MaxChunkSize: 1 << 20, // 1 MiB
+ GossipMaxSize: 15728640,
+ GossipMaxSizeBellatrix: 15728640,
+ MaxChunkSize: 15728640,
AttestationSubnetCount: 64,
AttestationPropagationSlotRange: 32,
MaxRequestBlocks: 1 << 10, // 1024
@@ -248,9 +249,9 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig
},
GnosisNetwork: {
- GossipMaxSize: 1 << 20, // 1 MiB
- GossipMaxSizeBellatrix: 10485760,
- MaxChunkSize: 1 << 20, // 1 MiB
+ GossipMaxSize: 15728640, // 15 MiB
+ GossipMaxSizeBellatrix: 15728640,
+ MaxChunkSize: 15728640, // 15 MiB
AttestationSubnetCount: 64,
AttestationPropagationSlotRange: 32,
MaxRequestBlocks: 1 << 10, // 1024
@@ -267,9 +268,9 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig
},
ChiadoNetwork: {
- GossipMaxSize: 1 << 20, // 1 MiB
- GossipMaxSizeBellatrix: 10485760,
- MaxChunkSize: 1 << 20, // 1 MiB
+ GossipMaxSize: 15728640, // 15 MiB
+ GossipMaxSizeBellatrix: 15728640,
+ MaxChunkSize: 15728640, // 15 MiB
AttestationSubnetCount: 64,
AttestationPropagationSlotRange: 32,
MaxRequestBlocks: 1 << 10, // 1024
@@ -286,9 +287,9 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig
},
HoleskyNetwork: {
- GossipMaxSize: 1 << 20, // 1 MiB
- GossipMaxSizeBellatrix: 10485760,
- MaxChunkSize: 1 << 20, // 1 MiB
+ GossipMaxSize: 15728640, // 15 MiB
+ GossipMaxSizeBellatrix: 15728640,
+ MaxChunkSize: 15728640, // 15 MiB
AttestationSubnetCount: 64,
AttestationPropagationSlotRange: 32,
MaxRequestBlocks: 1 << 10, // 1024
@@ -531,11 +532,10 @@ type BeaconChainConfig struct {
MinSyncCommitteeParticipants uint64 `yaml:"MIN_SYNC_COMMITTEE_PARTICIPANTS" spec:"true" json:"MIN_SYNC_COMMITTEE_PARTICIPANTS,string"` // MinSyncCommitteeParticipants defines the minimum amount of sync committee participants for which the light client acknowledges the signature.
// Bellatrix
- TerminalBlockHash libcommon.Hash `yaml:"TERMINAL_BLOCK_HASH" spec:"true" json:"TERMINAL_BLOCK_HASH"` // TerminalBlockHash of beacon chain.
- TerminalBlockHashActivationEpoch uint64 `yaml:"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH" spec:"true" json:"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH,string"` // TerminalBlockHashActivationEpoch of beacon chain.
- TerminalTotalDifficulty string `yaml:"TERMINAL_TOTAL_DIFFICULTY" spec:"true" json:"TERMINAL_TOTAL_DIFFICULTY"` // TerminalTotalDifficulty is part of the experimental Bellatrix spec. This value is type is currently TBD.
- DefaultFeeRecipient libcommon.Address `json:"-"` // DefaultFeeRecipient where the transaction fee goes to.
- DefaultBuilderGasLimit uint64 `json:"-"` // DefaultBuilderGasLimit is the default used to set the gaslimit for the Builder APIs, typically at around 30M wei.
+ TerminalBlockHash libcommon.Hash `yaml:"TERMINAL_BLOCK_HASH" spec:"true" json:"TERMINAL_BLOCK_HASH"` // TerminalBlockHash of beacon chain.
+ TerminalBlockHashActivationEpoch uint64 `yaml:"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH" spec:"true" json:"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH,string"` // TerminalBlockHashActivationEpoch of beacon chain.
+ TerminalTotalDifficulty string `yaml:"TERMINAL_TOTAL_DIFFICULTY" spec:"true" json:"TERMINAL_TOTAL_DIFFICULTY"` // TerminalTotalDifficulty is part of the experimental Bellatrix spec. This value is type is currently TBD.
+ DefaultBuilderGasLimit uint64 `json:"-"` // DefaultBuilderGasLimit is the default used to set the gaslimit for the Builder APIs, typically at around 30M wei.
// Mev-boost circuit breaker
MaxBuilderConsecutiveMissedSlots uint64 `json:"-"` // MaxBuilderConsecutiveMissedSlots defines the number of consecutive skip slot to fallback from using relay/builder to local execution engine for block construction.
@@ -804,7 +804,7 @@ var MainnetBeaconConfig BeaconChainConfig = BeaconChainConfig{
TerminalBlockHashActivationEpoch: 18446744073709551615,
TerminalBlockHash: [32]byte{},
TerminalTotalDifficulty: "58750000000000000000000", // Estimated: Sept 15, 2022
- DefaultBuilderGasLimit: uint64(30000000),
+ DefaultBuilderGasLimit: uint64(36000000),
// Mevboost circuit breaker
MaxBuilderConsecutiveMissedSlots: 3,
diff --git a/cl/persistence/state/historical_states_reader/historical_states_reader.go b/cl/persistence/state/historical_states_reader/historical_states_reader.go
index 7f6b9821b84..a2536572f2b 100644
--- a/cl/persistence/state/historical_states_reader/historical_states_reader.go
+++ b/cl/persistence/state/historical_states_reader/historical_states_reader.go
@@ -28,6 +28,7 @@ import (
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon-lib/log/v3"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/cltypes"
"github.com/erigontech/erigon/cl/cltypes/solid"
@@ -50,6 +51,7 @@ type HistoricalStatesReader struct {
blockReader freezeblocks.BeaconSnapshotReader
stateSn *snapshotsync.CaplinStateSnapshots
genesisState *state.CachingBeaconState
+ syncedData synced_data.SyncedData
shuffledIndiciesCache *lru.CacheWithTTL[uint64, []uint64]
}
@@ -58,7 +60,8 @@ func NewHistoricalStatesReader(
cfg *clparams.BeaconChainConfig,
blockReader freezeblocks.BeaconSnapshotReader,
validatorTable *state_accessors.StaticValidatorTable,
- genesisState *state.CachingBeaconState, stateSn *snapshotsync.CaplinStateSnapshots) *HistoricalStatesReader {
+ genesisState *state.CachingBeaconState, stateSn *snapshotsync.CaplinStateSnapshots,
+ syncedData synced_data.SyncedData) *HistoricalStatesReader {
shuffledIndiciesCache := lru.NewWithTTL[uint64, []uint64]("shuffledIndiciesCacheReader", 64, 2*time.Minute)
return &HistoricalStatesReader{
@@ -68,6 +71,7 @@ func NewHistoricalStatesReader(
validatorTable: validatorTable,
stateSn: stateSn,
shuffledIndiciesCache: shuffledIndiciesCache,
+ syncedData: syncedData,
}
}
@@ -110,7 +114,7 @@ func (r *HistoricalStatesReader) ReadHistoricalState(ctx context.Context, tx kv.
blockHeader := block.SignedBeaconBlockHeader().Header
blockHeader.Root = common.Hash{}
// Read the epoch and per-slot data.
- slotData, err := state_accessors.ReadSlotData(kvGetter, slot)
+ slotData, err := state_accessors.ReadSlotData(kvGetter, slot, r.cfg)
if err != nil {
return nil, err
}
@@ -150,12 +154,14 @@ func (r *HistoricalStatesReader) ReadHistoricalState(ctx context.Context, tx kv.
ret.SetStateRoots(stateRoots)
historicalRoots := solid.NewHashList(int(r.cfg.HistoricalRootsLimit))
- if err := state_accessors.ReadHistoricalRoots(tx, epochData.HistoricalRootsLength, func(idx int, root common.Hash) error {
- historicalRoots.Append(root)
- return nil
- }); err != nil {
- return nil, fmt.Errorf("failed to read historical roots: %w", err)
+ for i := 0; i < int(epochData.HistoricalRootsLength); i++ {
+ historicalRoot, err := r.syncedData.HistoricalRootElementAtIndex(i)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read historical root at index %d: %w", i, err)
+ }
+ historicalRoots.Append(historicalRoot)
}
+
ret.SetHistoricalRoots(historicalRoots)
// Eth1
@@ -277,11 +283,13 @@ func (r *HistoricalStatesReader) ReadHistoricalState(ctx context.Context, tx kv.
ret.SetNextWithdrawalValidatorIndex(slotData.NextWithdrawalValidatorIndex)
// Deep history valid from Capella onwards
historicalSummaries := solid.NewStaticListSSZ[*cltypes.HistoricalSummary](int(r.cfg.HistoricalRootsLimit), 64)
- if err := state_accessors.ReadHistoricalSummaries(tx, epochData.HistoricalSummariesLength, func(idx int, historicalSummary *cltypes.HistoricalSummary) error {
+
+ for i := 0; i < int(epochData.HistoricalSummariesLength); i++ {
+ historicalSummary, err := r.syncedData.HistoricalSummaryElementAtIndex(i)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read historical summary at index %d: %w", i, err)
+ }
historicalSummaries.Append(historicalSummary)
- return nil
- }); err != nil {
- return nil, fmt.Errorf("failed to read historical summaries: %w", err)
}
ret.SetHistoricalSummaries(historicalSummaries)
return ret, nil
@@ -665,7 +673,7 @@ func (r *HistoricalStatesReader) ReconstructUint64ListDump(kvGetter state_access
func (r *HistoricalStatesReader) ReadValidatorsForHistoricalState(tx kv.Tx, kvGetter state_accessors.GetValFn, slot uint64) (*solid.ValidatorSet, error) {
// Read the minimal beacon state which have the small fields.
- sd, err := state_accessors.ReadSlotData(kvGetter, slot)
+ sd, err := state_accessors.ReadSlotData(kvGetter, slot, r.cfg)
if err != nil {
return nil, err
}
@@ -769,7 +777,7 @@ func (r *HistoricalStatesReader) ReadParticipations(tx kv.Tx, kvGetter state_acc
}
// Read the minimal beacon state which have the small fields.
- sd, err := state_accessors.ReadSlotData(kvGetter, slot)
+ sd, err := state_accessors.ReadSlotData(kvGetter, slot, r.cfg)
if err != nil {
return nil, nil, err
}
@@ -892,7 +900,7 @@ func (r *HistoricalStatesReader) tryCachingEpochsInParallell(tx kv.Tx, kvGetter
}
func (r *HistoricalStatesReader) ReadValidatorsBalances(tx kv.Tx, kvGetter state_accessors.GetValFn, slot uint64) (solid.Uint64ListSSZ, error) {
- sd, err := state_accessors.ReadSlotData(kvGetter, slot)
+ sd, err := state_accessors.ReadSlotData(kvGetter, slot, r.cfg)
if err != nil {
return nil, err
}
diff --git a/cl/persistence/state/historical_states_reader/historical_states_reader_test.go b/cl/persistence/state/historical_states_reader/historical_states_reader_test.go
index 5a2052a546c..7d21448db2b 100644
--- a/cl/persistence/state/historical_states_reader/historical_states_reader_test.go
+++ b/cl/persistence/state/historical_states_reader/historical_states_reader_test.go
@@ -29,6 +29,7 @@ import (
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/cl/antiquary"
"github.com/erigontech/erigon/cl/antiquary/tests"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/cltypes"
state_accessors "github.com/erigontech/erigon/cl/persistence/state"
@@ -40,9 +41,11 @@ func runTest(t *testing.T, blocks []*cltypes.SignedBeaconBlock, preState, postSt
db := memdb.NewTestDB(t, kv.ChainDB)
reader := tests.LoadChain(blocks, postState, db, t)
+ sn := synced_data.NewSyncedDataManager(&clparams.MainnetBeaconConfig, true)
+ sn.OnHeadState(postState)
ctx := context.Background()
vt := state_accessors.NewStaticValidatorTable()
- a := antiquary.NewAntiquary(ctx, nil, preState, vt, &clparams.MainnetBeaconConfig, datadir.New("/tmp"), nil, db, nil, nil, reader, log.New(), true, true, true, false, nil)
+ a := antiquary.NewAntiquary(ctx, nil, preState, vt, &clparams.MainnetBeaconConfig, datadir.New("/tmp"), nil, db, nil, nil, reader, sn, log.New(), true, true, true, false, nil)
require.NoError(t, a.IncrementBeaconState(ctx, blocks[len(blocks)-1].Block.Slot+33))
// Now lets test it against the reader
tx, err := db.BeginRw(ctx)
@@ -51,7 +54,7 @@ func runTest(t *testing.T, blocks []*cltypes.SignedBeaconBlock, preState, postSt
vt = state_accessors.NewStaticValidatorTable()
require.NoError(t, state_accessors.ReadValidatorsTable(tx, vt))
- hr := historical_states_reader.NewHistoricalStatesReader(&clparams.MainnetBeaconConfig, reader, vt, preState, nil)
+ hr := historical_states_reader.NewHistoricalStatesReader(&clparams.MainnetBeaconConfig, reader, vt, preState, nil, sn)
s, err := hr.ReadHistoricalState(ctx, tx, blocks[len(blocks)-1].Block.Slot)
require.NoError(t, err)
diff --git a/cl/persistence/state/slot_data.go b/cl/persistence/state/slot_data.go
index eca6c12c073..8f23427cde5 100644
--- a/cl/persistence/state/slot_data.go
+++ b/cl/persistence/state/slot_data.go
@@ -23,6 +23,7 @@ import (
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/cltypes"
+ "github.com/erigontech/erigon/cl/cltypes/solid"
"github.com/erigontech/erigon/cl/phase1/core/state"
ssz2 "github.com/erigontech/erigon/cl/ssz"
)
@@ -40,6 +41,16 @@ type SlotData struct {
// Capella
NextWithdrawalIndex uint64
NextWithdrawalValidatorIndex uint64
+ // Electra
+ DepositRequestsStartIndex uint64
+ DepositBalanceToConsume uint64
+ ExitBalanceToConsume uint64
+ EarliestExitEpoch uint64
+ ConsolidationBalanceToConsume uint64
+ EarliestConsolidationEpoch uint64
+ PendingDeposits *solid.ListSSZ[*solid.PendingDeposit]
+ PendingPartialWithdrawals *solid.ListSSZ[*solid.PendingPartialWithdrawal]
+ PendingConsolidations *solid.ListSSZ[*solid.PendingConsolidation]
// BlockRewards for proposer
AttestationsRewards uint64
@@ -56,12 +67,21 @@ func SlotDataFromBeaconState(s *state.CachingBeaconState) *SlotData {
ValidatorLength: uint64(s.ValidatorLength()),
Eth1DataLength: uint64(s.Eth1DataVotes().Len()),
- Version: s.Version(),
- Eth1Data: s.Eth1Data(),
- Eth1DepositIndex: s.Eth1DepositIndex(),
- NextWithdrawalIndex: s.NextWithdrawalIndex(),
- NextWithdrawalValidatorIndex: s.NextWithdrawalValidatorIndex(),
- Fork: s.Fork(),
+ Version: s.Version(),
+ Eth1Data: s.Eth1Data(),
+ Eth1DepositIndex: s.Eth1DepositIndex(),
+ NextWithdrawalIndex: s.NextWithdrawalIndex(),
+ NextWithdrawalValidatorIndex: s.NextWithdrawalValidatorIndex(),
+ DepositRequestsStartIndex: s.DepositRequestsStartIndex(),
+ DepositBalanceToConsume: s.DepositBalanceToConsume(),
+ ExitBalanceToConsume: s.ExitBalanceToConsume(),
+ EarliestExitEpoch: s.EarliestExitEpoch(),
+ ConsolidationBalanceToConsume: s.ConsolidationBalanceToConsume(),
+ EarliestConsolidationEpoch: s.EarliestConsolidationEpoch(),
+ PendingDeposits: s.PendingDeposits(),
+ PendingPartialWithdrawals: s.PendingPartialWithdrawals(),
+ PendingConsolidations: s.PendingConsolidations(),
+ Fork: s.Fork(),
}
}
@@ -87,7 +107,7 @@ func (m *SlotData) WriteTo(w io.Writer) error {
}
// Deserialize deserializes the state from a byte slice with zstd compression.
-func (m *SlotData) ReadFrom(r io.Reader) error {
+func (m *SlotData) ReadFrom(r io.Reader, cfg *clparams.BeaconChainConfig) error {
m.Eth1Data = &cltypes.Eth1Data{}
m.Fork = &cltypes.Fork{}
var err error
@@ -98,6 +118,12 @@ func (m *SlotData) ReadFrom(r io.Reader) error {
}
m.Version = clparams.StateVersion(versionByte[0])
+ if m.Version >= clparams.ElectraVersion {
+ m.PendingDeposits = solid.NewPendingDepositList(cfg)
+ m.PendingPartialWithdrawals = solid.NewPendingWithdrawalList(cfg)
+ m.PendingConsolidations = solid.NewPendingConsolidationList(cfg)
+ }
+
lenB := make([]byte, 8)
if _, err = r.Read(lenB); err != nil {
return err
@@ -122,5 +148,19 @@ func (m *SlotData) getSchema() []interface{} {
if m.Version >= clparams.CapellaVersion {
schema = append(schema, &m.NextWithdrawalIndex, &m.NextWithdrawalValidatorIndex)
}
+
+ if m.Version >= clparams.ElectraVersion {
+ schema = append(schema,
+ &m.DepositRequestsStartIndex,
+ &m.DepositBalanceToConsume,
+ &m.ExitBalanceToConsume,
+ &m.EarliestExitEpoch,
+ &m.ConsolidationBalanceToConsume,
+ &m.EarliestConsolidationEpoch,
+ m.PendingDeposits,
+ m.PendingPartialWithdrawals,
+ m.PendingConsolidations,
+ )
+ }
return schema
}
diff --git a/cl/persistence/state/slot_data_test.go b/cl/persistence/state/slot_data_test.go
index 886b4417cba..9b4d91688e6 100644
--- a/cl/persistence/state/slot_data_test.go
+++ b/cl/persistence/state/slot_data_test.go
@@ -21,25 +21,38 @@ import (
"testing"
"github.com/erigontech/erigon/cl/clparams"
+ "github.com/erigontech/erigon/cl/clparams/initial_state"
"github.com/erigontech/erigon/cl/cltypes"
+ "github.com/erigontech/erigon/cl/cltypes/solid"
"github.com/stretchr/testify/require"
)
func TestSlotData(t *testing.T) {
+ s, err := initial_state.GetGenesisState(clparams.MainnetNetwork)
+ require.NoError(t, err)
m := &SlotData{
- Version: clparams.CapellaVersion,
- Eth1Data: &cltypes.Eth1Data{},
- Eth1DepositIndex: 0,
- NextWithdrawalIndex: 0,
- NextWithdrawalValidatorIndex: 0,
- Fork: &cltypes.Fork{Epoch: 12},
+ Version: clparams.ElectraVersion,
+ Eth1Data: &cltypes.Eth1Data{},
+ Eth1DepositIndex: 1,
+ NextWithdrawalIndex: 2,
+ NextWithdrawalValidatorIndex: 3,
+ DepositRequestsStartIndex: 4,
+ DepositBalanceToConsume: 5,
+ ExitBalanceToConsume: 6,
+ EarliestExitEpoch: 7,
+ ConsolidationBalanceToConsume: 8,
+ EarliestConsolidationEpoch: 9,
+ PendingDeposits: solid.NewPendingDepositList(s.BeaconConfig()),
+ PendingPartialWithdrawals: solid.NewPendingWithdrawalList(s.BeaconConfig()),
+ PendingConsolidations: solid.NewPendingConsolidationList(s.BeaconConfig()),
+ Fork: &cltypes.Fork{Epoch: 12},
}
var b bytes.Buffer
if err := m.WriteTo(&b); err != nil {
t.Fatal(err)
}
m2 := &SlotData{}
- if err := m2.ReadFrom(&b); err != nil {
+ if err := m2.ReadFrom(&b, s.BeaconConfig()); err != nil {
t.Fatal(err)
}
diff --git a/cl/persistence/state/state_accessors.go b/cl/persistence/state/state_accessors.go
index 6292484e518..143cf1189b4 100644
--- a/cl/persistence/state/state_accessors.go
+++ b/cl/persistence/state/state_accessors.go
@@ -21,13 +21,10 @@ import (
"encoding/binary"
"github.com/erigontech/erigon-lib/kv"
- "github.com/erigontech/erigon/cl/cltypes"
+ "github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/cltypes/solid"
"github.com/erigontech/erigon/cl/persistence/base_encoding"
- "github.com/erigontech/erigon/cl/phase1/core/state"
"github.com/erigontech/erigon/turbo/snapshotsync"
-
- libcommon "github.com/erigontech/erigon-lib/common"
)
type GetValFn func(table string, key []byte) ([]byte, error)
@@ -45,137 +42,6 @@ func GetValFnTxAndSnapshot(tx kv.Tx, snapshotRoTx *snapshotsync.CaplinStateView)
}
}
-// InitializeValidatorTable initializes the validator table in the database.
-func InitializeStaticTables(tx kv.RwTx, state *state.CachingBeaconState) error {
- var err error
- if err = tx.ClearBucket(kv.ValidatorPublicKeys); err != nil {
- return err
- }
- if err = tx.ClearBucket(kv.HistoricalRoots); err != nil {
- return err
- }
- if err = tx.ClearBucket(kv.HistoricalSummaries); err != nil {
- return err
- }
- state.ForEachValidator(func(v solid.Validator, idx, total int) bool {
- key := base_encoding.Encode64ToBytes4(uint64(idx))
- if err = tx.Append(kv.ValidatorPublicKeys, key, v.PublicKeyBytes()); err != nil {
- return false
- }
- if err = tx.Put(kv.InvertedValidatorPublicKeys, v.PublicKeyBytes(), key); err != nil {
- return false
- }
- return true
- })
- if err != nil {
- return err
- }
- for i := 0; i < int(state.HistoricalRootsLength()); i++ {
- key := base_encoding.Encode64ToBytes4(uint64(i))
- root := state.HistoricalRoot(i)
- if err = tx.Append(kv.HistoricalRoots, key, root[:]); err != nil {
- return err
- }
- }
- var temp []byte
- for i := 0; i < int(state.HistoricalSummariesLength()); i++ {
- temp = temp[:0]
- key := base_encoding.Encode64ToBytes4(uint64(i))
- summary := state.HistoricalSummary(i)
- temp, err = summary.EncodeSSZ(temp)
- if err != nil {
- return err
- }
- if err = tx.Append(kv.HistoricalSummaries, key, temp); err != nil {
- return err
- }
- }
- return err
-}
-
-// IncrementValidatorTable increments the validator table in the database, by ignoring all the preverified indices.
-func IncrementPublicKeyTable(tx kv.RwTx, state *state.CachingBeaconState, preverifiedIndicies uint64) error {
- valLength := state.ValidatorLength()
- for i := preverifiedIndicies; i < uint64(valLength); i++ {
- key := base_encoding.Encode64ToBytes4(i)
- pubKey, err := state.ValidatorPublicKey(int(i))
- if err != nil {
- return err
- }
- // We put as there could be reorgs and thus some of overwriting
- if err := tx.Put(kv.ValidatorPublicKeys, key, pubKey[:]); err != nil {
- return err
- }
- if err := tx.Put(kv.InvertedValidatorPublicKeys, pubKey[:], key); err != nil {
- return err
- }
- }
- return nil
-}
-
-func IncrementHistoricalRootsTable(tx kv.RwTx, state *state.CachingBeaconState, preverifiedIndicies uint64) error {
- for i := preverifiedIndicies; i < state.HistoricalRootsLength(); i++ {
- key := base_encoding.Encode64ToBytes4(i)
- root := state.HistoricalRoot(int(i))
- if err := tx.Put(kv.HistoricalRoots, key, root[:]); err != nil {
- return err
- }
- }
- return nil
-}
-
-func IncrementHistoricalSummariesTable(tx kv.RwTx, state *state.CachingBeaconState, preverifiedIndicies uint64) error {
- var temp []byte
- var err error
- for i := preverifiedIndicies; i < state.HistoricalSummariesLength(); i++ {
- temp = temp[:0]
- key := base_encoding.Encode64ToBytes4(i)
- summary := state.HistoricalSummary(int(i))
- temp, err = summary.EncodeSSZ(temp)
- if err != nil {
- return err
- }
- if err = tx.Put(kv.HistoricalSummaries, key, temp); err != nil {
- return err
- }
- }
- return nil
-}
-
-func ReadPublicKeyByIndexNoCopy(tx kv.Tx, index uint64) ([]byte, error) {
- var pks []byte
- var err error
- key := base_encoding.Encode64ToBytes4(index)
- if pks, err = tx.GetOne(kv.ValidatorPublicKeys, key); err != nil {
- return nil, err
- }
- return pks, err
-}
-
-func ReadPublicKeyByIndex(tx kv.Tx, index uint64) (libcommon.Bytes48, error) {
- var pks []byte
- var err error
- key := base_encoding.Encode64ToBytes4(index)
- if pks, err = tx.GetOne(kv.ValidatorPublicKeys, key); err != nil {
- return libcommon.Bytes48{}, err
- }
- var ret libcommon.Bytes48
- copy(ret[:], pks)
- return ret, err
-}
-
-func ReadValidatorIndexByPublicKey(tx kv.Tx, key libcommon.Bytes48) (uint64, bool, error) {
- var index []byte
- var err error
- if index, err = tx.GetOne(kv.InvertedValidatorPublicKeys, key[:]); err != nil {
- return 0, false, err
- }
- if len(index) == 0 {
- return 0, false, nil
- }
- return base_encoding.Decode64FromBytes4(index), true, nil
-}
-
func GetStateProcessingProgress(tx kv.Tx) (uint64, error) {
progressByytes, err := tx.GetOne(kv.StatesProcessingProgress, kv.StatesProcessingKey)
if err != nil {
@@ -191,7 +57,7 @@ func SetStateProcessingProgress(tx kv.RwTx, progress uint64) error {
return tx.Put(kv.StatesProcessingProgress, kv.StatesProcessingKey, base_encoding.Encode64ToBytes4(progress))
}
-func ReadSlotData(getFn GetValFn, slot uint64) (*SlotData, error) {
+func ReadSlotData(getFn GetValFn, slot uint64, cfg *clparams.BeaconChainConfig) (*SlotData, error) {
sd := &SlotData{}
v, err := getFn(kv.SlotData, base_encoding.Encode64ToBytes4(slot))
if err != nil {
@@ -202,7 +68,7 @@ func ReadSlotData(getFn GetValFn, slot uint64) (*SlotData, error) {
}
buf := bytes.NewBuffer(v)
- return sd, sd.ReadFrom(buf)
+ return sd, sd.ReadFrom(buf, cfg)
}
func ReadEpochData(getFn GetValFn, slot uint64) (*EpochData, error) {
@@ -266,38 +132,6 @@ func ReadCurrentSyncCommittee(getFn GetValFn, slot uint64) (committee *solid.Syn
return
}
-func ReadHistoricalRoots(tx kv.Tx, l uint64, fn func(idx int, root libcommon.Hash) error) error {
- for i := 0; i < int(l); i++ {
- key := base_encoding.Encode64ToBytes4(uint64(i))
- v, err := tx.GetOne(kv.HistoricalRoots, key)
- if err != nil {
- return err
- }
- if err := fn(i, libcommon.BytesToHash(v)); err != nil {
- return err
- }
- }
- return nil
-}
-
-func ReadHistoricalSummaries(tx kv.Tx, l uint64, fn func(idx int, historicalSummary *cltypes.HistoricalSummary) error) error {
- for i := 0; i < int(l); i++ {
- key := base_encoding.Encode64ToBytes4(uint64(i))
- v, err := tx.GetOne(kv.HistoricalSummaries, key)
- if err != nil {
- return err
- }
- historicalSummary := &cltypes.HistoricalSummary{}
- if err := historicalSummary.DecodeSSZ(v, 0); err != nil {
- return err
- }
- if err := fn(i, historicalSummary); err != nil {
- return err
- }
- }
- return nil
-}
-
func ReadValidatorsTable(tx kv.Tx, out *StaticValidatorTable) error {
cursor, err := tx.Cursor(kv.StaticValidators)
if err != nil {
diff --git a/cl/phase1/core/state/raw/getters.go b/cl/phase1/core/state/raw/getters.go
index 688bb216c91..5ad68c09a9f 100644
--- a/cl/phase1/core/state/raw/getters.go
+++ b/cl/phase1/core/state/raw/getters.go
@@ -323,6 +323,34 @@ func (b *BeaconState) NextWithdrawalValidatorIndex() uint64 {
return b.nextWithdrawalValidatorIndex
}
+func (b *BeaconState) DepositRequestsStartIndex() uint64 {
+ return b.depositRequestsStartIndex
+}
+
+func (b *BeaconState) DepositBalanceToConsume() uint64 {
+ return b.depositBalanceToConsume
+}
+
+func (b *BeaconState) ConsolidationBalanceToConsume() uint64 {
+ return b.consolidationBalanceToConsume
+}
+
+func (b *BeaconState) EarliestConsolidationEpoch() uint64 {
+ return b.earliestConsolidationEpoch
+}
+
+func (b *BeaconState) PendingDeposits() *solid.ListSSZ[*solid.PendingDeposit] {
+ return b.pendingDeposits
+}
+
+func (b *BeaconState) PendingPartialWithdrawals() *solid.ListSSZ[*solid.PendingPartialWithdrawal] {
+ return b.pendingPartialWithdrawals
+}
+
+func (b *BeaconState) PendingConsolidations() *solid.ListSSZ[*solid.PendingConsolidation] {
+ return b.pendingConsolidations
+}
+
// more compluicated ones
// GetBlockRootAtSlot returns the block root at a given slot
diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go
index 51b7ca140ff..d6871893689 100644
--- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go
+++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go
@@ -86,6 +86,7 @@ func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash, out *s
if err = bs.DecodeSSZ(f.sszBuffer, int(v[0])); err != nil {
return nil, fmt.Errorf("failed to decode beacon state: %w, root: %x, len: %d, decLen: %d, bs: %+v", err, blockRoot, n, len(f.sszBuffer), bs)
}
+
// decode the cache file
cacheFile, err := f.fs.Open(getBeaconStateCacheFilename(blockRoot))
if err != nil {
@@ -93,7 +94,13 @@ func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash, out *s
}
defer cacheFile.Close()
- if err := bs.DecodeCaches(cacheFile); err != nil {
+ f.sszBuffer = f.sszBuffer[:0]
+ b := bytes.NewBuffer(f.sszBuffer)
+ if _, err := io.Copy(b, cacheFile); err != nil {
+ return nil, err
+ }
+
+ if err := bs.DecodeCaches(b); err != nil {
return nil, err
}
diff --git a/cl/phase1/forkchoice/on_attestation.go b/cl/phase1/forkchoice/on_attestation.go
index 7544509b311..deeb757442a 100644
--- a/cl/phase1/forkchoice/on_attestation.go
+++ b/cl/phase1/forkchoice/on_attestation.go
@@ -56,7 +56,6 @@ func (f *ForkChoiceStore) OnAttestation(
return err
}
}
-
var attestationIndicies []uint64
var err error
target := data.Target
diff --git a/cl/phase1/forkchoice/on_attester_slashing.go b/cl/phase1/forkchoice/on_attester_slashing.go
index 9879ffece91..38263819d06 100644
--- a/cl/phase1/forkchoice/on_attester_slashing.go
+++ b/cl/phase1/forkchoice/on_attester_slashing.go
@@ -60,7 +60,6 @@ func (f *ForkChoiceStore) onProcessAttesterSlashing(attesterSlashing *cltypes.At
if !cltypes.IsSlashableAttestationData(attestation1.Data, attestation2.Data) {
return errors.New("attestation data is not slashable")
}
-
attestation1PublicKeys, err := getIndexedAttestationPublicKeys(s, attestation1)
if err != nil {
return err
diff --git a/cl/phase1/forkchoice/public_keys_registry/db_public_keys_registry.go b/cl/phase1/forkchoice/public_keys_registry/db_public_keys_registry.go
index c6822ddb42b..a986933114f 100644
--- a/cl/phase1/forkchoice/public_keys_registry/db_public_keys_registry.go
+++ b/cl/phase1/forkchoice/public_keys_registry/db_public_keys_registry.go
@@ -1,22 +1,19 @@
package public_keys_registry
import (
- "context"
-
"github.com/Giulio2002/bls"
"github.com/erigontech/erigon-lib/common"
- "github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon/cl/abstract"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/cltypes/solid"
- state_accessors "github.com/erigontech/erigon/cl/persistence/state"
)
type DBPublicKeysRegistry struct {
- db kv.RoDB
+ headView synced_data.SyncedData
}
-func NewDBPublicKeysRegistry(db kv.RoDB) *DBPublicKeysRegistry {
- return &DBPublicKeysRegistry{db: db}
+func NewHeadViewPublicKeysRegistry(headView synced_data.SyncedData) *DBPublicKeysRegistry {
+ return &DBPublicKeysRegistry{headView: headView}
}
// ResetAnchor resets the public keys registry to the anchor state
@@ -28,19 +25,14 @@ func (r *DBPublicKeysRegistry) ResetAnchor(s abstract.BeaconState) {
func (r *DBPublicKeysRegistry) VerifyAggregateSignature(checkpoint solid.Checkpoint, pubkeysIdxs *solid.RawUint64List, message []byte, signature common.Bytes96) (bool, error) {
pks := make([][]byte, 0, pubkeysIdxs.Length())
- if err := r.db.View(context.TODO(), func(tx kv.Tx) error {
- pubkeysIdxs.Range(func(_ int, value uint64, length int) bool {
- pk, err := state_accessors.ReadPublicKeyByIndexNoCopy(tx, value)
- if err != nil {
- return false
- }
- pks = append(pks, pk)
- return true
- })
- return nil
- }); err != nil {
- return false, err
- }
+ pubkeysIdxs.Range(func(_ int, value uint64, length int) bool {
+ pk, err := r.headView.ValidatorPublicKeyByIndex(int(value))
+ if err != nil {
+ return false
+ }
+ pks = append(pks, pk[:])
+ return true
+ })
return bls.VerifyAggregate(signature[:], message, pks)
}
diff --git a/cl/phase1/network/services/block_service.go b/cl/phase1/network/services/block_service.go
index 56ed8be96e8..a7fab891c70 100644
--- a/cl/phase1/network/services/block_service.go
+++ b/cl/phase1/network/services/block_service.go
@@ -156,7 +156,6 @@ func (b *blockService) ProcessMessage(ctx context.Context, _ *uint64, msg *cltyp
if msg.Block.Body.BlobKzgCommitments.Len() > int(b.beaconCfg.MaxBlobsPerBlock) {
return ErrInvalidCommitmentsCount
}
-
b.publishBlockGossipEvent(msg)
// the rest of the validation is done in the forkchoice store
if err := b.processAndStoreBlock(ctx, msg); err != nil {
diff --git a/cl/phase1/stages/forkchoice.go b/cl/phase1/stages/forkchoice.go
index e4d51ccaed5..3c1de440594 100644
--- a/cl/phase1/stages/forkchoice.go
+++ b/cl/phase1/stages/forkchoice.go
@@ -20,7 +20,6 @@ import (
"github.com/erigontech/erigon/cl/monitor"
"github.com/erigontech/erigon/cl/monitor/shuffling_metrics"
"github.com/erigontech/erigon/cl/persistence/beacon_indicies"
- state_accessors "github.com/erigontech/erigon/cl/persistence/state"
"github.com/erigontech/erigon/cl/phase1/core/caches"
"github.com/erigontech/erigon/cl/phase1/core/state"
"github.com/erigontech/erigon/cl/phase1/core/state/shuffling"
@@ -194,24 +193,6 @@ func updateCanonicalChainInTheDatabase(ctx context.Context, tx kv.RwTx, headSlot
return nil
}
-// runIndexingRoutines runs the indexing routines for the database.
-func runIndexingRoutines(ctx context.Context, tx kv.RwTx, cfg *Cfg, headState *state.CachingBeaconState) error {
- preverifiedValidators := cfg.forkChoice.PreverifiedValidator(headState.FinalizedCheckpoint().Root)
- preverifiedHistoricalSummary := cfg.forkChoice.PreverifiedHistoricalSummaries(headState.FinalizedCheckpoint().Root)
- preverifiedHistoricalRoots := cfg.forkChoice.PreverifiedHistoricalRoots(headState.FinalizedCheckpoint().Root)
-
- if err := state_accessors.IncrementPublicKeyTable(tx, headState, preverifiedValidators); err != nil {
- return fmt.Errorf("failed to increment public key table: %w", err)
- }
- if err := state_accessors.IncrementHistoricalSummariesTable(tx, headState, preverifiedHistoricalSummary); err != nil {
- return fmt.Errorf("failed to increment historical summaries table: %w", err)
- }
- if err := state_accessors.IncrementHistoricalRootsTable(tx, headState, preverifiedHistoricalRoots); err != nil {
- return fmt.Errorf("failed to increment historical roots table: %w", err)
- }
- return nil
-}
-
// emitHeadEvent emits the head event with the given head slot, head root, and head state.
func emitHeadEvent(cfg *Cfg, headSlot uint64, headRoot common.Hash, headState *state.CachingBeaconState) error {
headEpoch := headSlot / cfg.beaconCfg.SlotsPerEpoch
@@ -326,6 +307,9 @@ func postForkchoiceOperations(ctx context.Context, tx kv.RwTx, logger log.Logger
if _, err = cfg.attestationDataProducer.ProduceAndCacheAttestationData(tx, headState, headRoot, headState.Slot(), 0); err != nil {
logger.Warn("failed to produce and cache attestation data", "err", err)
}
+ if err := beacon_indicies.WriteHighestFinalized(tx, cfg.forkChoice.FinalizedSlot()); err != nil {
+ return err
+ }
start := time.Now()
cfg.forkChoice.SetSynced(true) // Now we are synced
// Update the head state with the new head state
@@ -337,13 +321,6 @@ func postForkchoiceOperations(ctx context.Context, tx kv.RwTx, logger log.Logger
}()
return cfg.syncedData.ViewHeadState(func(headState *state.CachingBeaconState) error {
- // Produce and cache attestation data for validator node (this is not an expensive operation so we can do it for all nodes)
-
- // Run indexing routines for the database
- if err := runIndexingRoutines(ctx, tx, cfg, headState); err != nil {
- return fmt.Errorf("failed to run indexing routines: %w", err)
- }
-
// Dump the head state on disk for ease of chain reorgs
if err := cfg.forkChoice.DumpBeaconStateOnDisk(headState); err != nil {
return fmt.Errorf("failed to dump beacon state on disk: %w", err)
diff --git a/cl/sentinel/sentinel.go b/cl/sentinel/sentinel.go
index d79283c1f49..8a0b94f85b3 100644
--- a/cl/sentinel/sentinel.go
+++ b/cl/sentinel/sentinel.go
@@ -273,7 +273,6 @@ func New(
}
func (s *Sentinel) observeBandwidth(ctx context.Context, bwc *metrics.BandwidthCounter) {
-
ticker := time.NewTicker(200 * time.Millisecond)
for {
countSubnetsSubscribed := func() int {
@@ -286,7 +285,7 @@ func (s *Sentinel) observeBandwidth(ctx context.Context, bwc *metrics.BandwidthC
if sub.topic == nil {
return true
}
- if strings.Contains(sub.topic.String(), "beacon_attestation") {
+ if strings.Contains(sub.topic.String(), "beacon_attestation") && sub.subscribed.Load() {
count++
}
return true
@@ -294,8 +293,10 @@ func (s *Sentinel) observeBandwidth(ctx context.Context, bwc *metrics.BandwidthC
return count
}()
- multiplierForAdaptableTraffic := (float64(countSubnetsSubscribed) / float64(s.cfg.NetworkConfig.AttestationSubnetCount)) * 8
-
+ multiplierForAdaptableTraffic := 1.0
+ if s.cfg.AdaptableTrafficRequirements {
+ multiplierForAdaptableTraffic = ((float64(countSubnetsSubscribed) / float64(s.cfg.NetworkConfig.AttestationSubnetCount)) * 8) + 1
+ }
select {
case <-ctx.Done():
return
@@ -308,7 +309,7 @@ func (s *Sentinel) observeBandwidth(ctx context.Context, bwc *metrics.BandwidthC
maxRateIn := float64(max(s.cfg.MaxInboundTrafficPerPeer, minBound)) * multiplierForAdaptableTraffic
maxRateOut := float64(max(s.cfg.MaxOutboundTrafficPerPeer, minBound)) * multiplierForAdaptableTraffic
peers := s.host.Network().Peers()
- maxPeersToBan := int(s.cfg.MaxPeerCount) / 8
+ maxPeersToBan := 16
// do not ban peers if we have less than 1/8 of max peer count
if len(peers) <= maxPeersToBan {
continue
diff --git a/cl/sentinel/sentinel_requests_test.go b/cl/sentinel/sentinel_requests_test.go
index 99545961640..c2eac7403c7 100644
--- a/cl/sentinel/sentinel_requests_test.go
+++ b/cl/sentinel/sentinel_requests_test.go
@@ -37,6 +37,7 @@ import (
"github.com/erigontech/erigon-lib/kv/memdb"
"github.com/erigontech/erigon/cl/antiquary"
"github.com/erigontech/erigon/cl/antiquary/tests"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/cltypes"
"github.com/erigontech/erigon/cl/cltypes/solid"
@@ -53,9 +54,12 @@ func loadChain(t *testing.T) (db kv.RwDB, blocks []*cltypes.SignedBeaconBlock, f
db = memdb.NewTestDB(t, kv.ChainDB)
reader = tests.LoadChain(blocks, postState, db, t)
+ sn := synced_data.NewSyncedDataManager(&clparams.MainnetBeaconConfig, true)
+ sn.OnHeadState(postState)
+
ctx := context.Background()
vt := state_accessors.NewStaticValidatorTable()
- a := antiquary.NewAntiquary(ctx, nil, preState, vt, &clparams.MainnetBeaconConfig, datadir.New("/tmp"), nil, db, nil, nil, reader, log.New(), true, true, false, false, nil)
+ a := antiquary.NewAntiquary(ctx, nil, preState, vt, &clparams.MainnetBeaconConfig, datadir.New("/tmp"), nil, db, nil, nil, reader, sn, log.New(), true, true, false, false, nil)
require.NoError(t, a.IncrementBeaconState(ctx, blocks[len(blocks)-1].Block.Slot+33))
return
}
diff --git a/cmd/capcli/cli.go b/cmd/capcli/cli.go
index a5563dad5c4..ae5250199be 100644
--- a/cmd/capcli/cli.go
+++ b/cmd/capcli/cli.go
@@ -45,6 +45,7 @@ import (
"github.com/erigontech/erigon-lib/metrics"
"github.com/erigontech/erigon/cl/antiquary"
+ "github.com/erigontech/erigon/cl/beacon/synced_data"
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/cl/clparams/initial_state"
"github.com/erigontech/erigon/cl/cltypes"
@@ -152,6 +153,7 @@ func (c *Chain) Run(ctx *Context) error {
if err != nil {
return err
}
+
ethClock := eth_clock.NewEthereumClock(bs.GenesisTime(), bs.GenesisValidatorsRoot(), beaconConfig)
db, blobStorage, err := caplin1.OpenCaplinDatabase(ctx, beaconConfig, ethClock, dirs.CaplinIndexing, dirs.CaplinBlobs, nil, false, 0)
if err != nil {
@@ -182,7 +184,7 @@ func (c *Chain) Run(ctx *Context) error {
}
downloader := network.NewBackwardBeaconDownloader(ctx, beacon, nil, nil, db)
- cfg := stages.StageHistoryReconstruction(downloader, antiquary.NewAntiquary(ctx, nil, nil, nil, nil, dirs, nil, nil, nil, nil, nil, nil, false, false, false, false, nil), csn, db, nil, beaconConfig, true, false, true, bRoot, bs.Slot(), "/tmp", 300*time.Millisecond, nil, nil, blobStorage, log.Root())
+ cfg := stages.StageHistoryReconstruction(downloader, antiquary.NewAntiquary(ctx, nil, nil, nil, nil, dirs, nil, nil, nil, nil, nil, nil, nil, false, false, false, false, nil), csn, db, nil, beaconConfig, true, false, true, bRoot, bs.Slot(), "/tmp", 300*time.Millisecond, nil, nil, blobStorage, log.Root())
return stages.SpawnStageHistoryDownload(cfg, ctx, log.Root())
}
@@ -599,8 +601,15 @@ func (r *RetrieveHistoricalState) Run(ctx *Context) error {
return err
}
+ bs, err := checkpoint_sync.NewRemoteCheckpointSync(beaconConfig, t).GetLatestBeaconState(ctx)
+ if err != nil {
+ return err
+ }
+ sn := synced_data.NewSyncedDataManager(beaconConfig, true)
+ sn.OnHeadState(bs)
+
r.withPPROF.withProfile()
- hr := historical_states_reader.NewHistoricalStatesReader(beaconConfig, snr, vt, gSpot, stateSn)
+ hr := historical_states_reader.NewHistoricalStatesReader(beaconConfig, snr, vt, gSpot, stateSn, sn)
start := time.Now()
haveState, err := hr.ReadHistoricalState(ctx, tx, r.CompareSlot)
if err != nil {
diff --git a/cmd/caplin/caplin1/run.go b/cmd/caplin/caplin1/run.go
index 5d389247af5..99877a288a2 100644
--- a/cmd/caplin/caplin1/run.go
+++ b/cmd/caplin/caplin1/run.go
@@ -273,7 +273,7 @@ func RunCaplinService(ctx context.Context, engine execution_client.ExecutionEngi
doLMDSampling := len(state.GetActiveValidatorsIndices(state.Slot()/beaconConfig.SlotsPerEpoch)) >= 20_000
// create the public keys registry
- pksRegistry := public_keys_registry.NewDBPublicKeysRegistry(indexDB)
+ pksRegistry := public_keys_registry.NewHeadViewPublicKeysRegistry(syncedDataManager)
forkChoice, err := forkchoice.NewForkChoiceStore(
ethClock, state, engine, pool, fork_graph.NewForkGraphDisk(state, fcuFs, config.BeaconAPIRouter, emitters),
@@ -385,9 +385,6 @@ func RunCaplinService(ctx context.Context, engine execution_client.ExecutionEngi
}
defer tx.Rollback()
- if err := state_accessors.InitializeStaticTables(tx, state); err != nil {
- return err
- }
if err := beacon_indicies.WriteHighestFinalized(tx, 0); err != nil {
return err
}
@@ -403,7 +400,7 @@ func RunCaplinService(ctx context.Context, engine execution_client.ExecutionEngi
if err := stateSnapshots.OpenFolder(); err != nil {
return err
}
- antiq := antiquary.NewAntiquary(ctx, blobStorage, genesisState, vTables, beaconConfig, dirs, snDownloader, indexDB, stateSnapshots, csn, rcsn, logger, states, backfilling, blobBackfilling, config.SnapshotGenerationEnabled, snBuildSema)
+ antiq := antiquary.NewAntiquary(ctx, blobStorage, genesisState, vTables, beaconConfig, dirs, snDownloader, indexDB, stateSnapshots, csn, rcsn, syncedDataManager, logger, states, backfilling, blobBackfilling, config.SnapshotGenerationEnabled, snBuildSema)
// Create the antiquary
go func() {
if err := antiq.Loop(); err != nil {
@@ -415,7 +412,7 @@ func RunCaplinService(ctx context.Context, engine execution_client.ExecutionEngi
return err
}
- statesReader := historical_states_reader.NewHistoricalStatesReader(beaconConfig, rcsn, vTables, genesisState, stateSnapshots)
+ statesReader := historical_states_reader.NewHistoricalStatesReader(beaconConfig, rcsn, vTables, genesisState, stateSnapshots, syncedDataManager)
validatorParameters := validator_params.NewValidatorParams()
if config.BeaconAPIRouter.Active {
apiHandler := handler.NewApiHandler(
diff --git a/cmd/devnet/contracts/gen.go b/cmd/devnet/contracts/gen.go
index 964f8498ed1..f9da61a64fa 100644
--- a/cmd/devnet/contracts/gen.go
+++ b/cmd/devnet/contracts/gen.go
@@ -42,4 +42,4 @@ package contracts
// faucet.sol
//go:generate solc --evm-version paris --allow-paths ., --abi --bin --overwrite --optimize -o build faucet.sol
-//go:generate abigen -abi build/Faucet.abi -bin build/Faucet.bin -pkg contracts -type Faucet -out ./gen_faucet.go
+//go:generate abigen -abi build/faucet.abi -bin build/faucet.bin -pkg contracts -type Faucet -out ./gen_faucet.go
diff --git a/cmd/devnet/contracts/gen_childreceiver.go b/cmd/devnet/contracts/gen_childreceiver.go
index 55b39a483bf..3dffdb0a1c4 100644
--- a/cmd/devnet/contracts/gen_childreceiver.go
+++ b/cmd/devnet/contracts/gen_childreceiver.go
@@ -1,4 +1,4 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// ChildReceiverABI is the input ABI used to generate the binding from.
@@ -242,8 +244,8 @@ func (_ChildReceiver *ChildReceiverTransactorSession) OnStateReceive(arg0 *big.I
return _ChildReceiver.Contract.OnStateReceive(&_ChildReceiver.TransactOpts, arg0, data)
}
-// OnStateReceiveParams is an auto generated read-only Go binding of transcaction calldata params
-type OnStateReceiveParams struct {
+// ChildReceiverOnStateReceiveParams is an auto generated read-only Go binding of transcaction calldata params
+type ChildReceiverOnStateReceiveParams struct {
Param_arg0 *big.Int
Param_data []byte
}
@@ -251,7 +253,7 @@ type OnStateReceiveParams struct {
// Parse OnStateReceive method from calldata of a transaction
//
// Solidity: function onStateReceive(uint256 , bytes data) returns()
-func ParseOnStateReceive(calldata []byte) (*OnStateReceiveParams, error) {
+func ParseChildReceiverOnStateReceiveParams(calldata []byte) (*ChildReceiverOnStateReceiveParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -266,7 +268,7 @@ func ParseOnStateReceive(calldata []byte) (*OnStateReceiveParams, error) {
return nil, fmt.Errorf("failed to unpack onStateReceive params data: %w", err)
}
- var paramsResult = new(OnStateReceiveParams)
+ var paramsResult = new(ChildReceiverOnStateReceiveParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -276,7 +278,7 @@ func ParseOnStateReceive(calldata []byte) (*OnStateReceiveParams, error) {
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
- return &OnStateReceiveParams{
+ return &ChildReceiverOnStateReceiveParams{
Param_arg0: out0, Param_data: out1,
}, nil
}
@@ -355,6 +357,10 @@ type ChildReceiverReceived struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_ChildReceiver *ChildReceiverFilterer) ReceivedEventID() libcommon.Hash {
+ return libcommon.HexToHash("0xf11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef")
+}
+
// FilterReceived is a free log retrieval operation binding the contract event 0xf11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef.
//
// Solidity: event received(address _source, uint256 _amount)
diff --git a/cmd/devnet/contracts/gen_childsender.go b/cmd/devnet/contracts/gen_childsender.go
index e0924f63bc0..8690c85a9db 100644
--- a/cmd/devnet/contracts/gen_childsender.go
+++ b/cmd/devnet/contracts/gen_childsender.go
@@ -1,4 +1,4 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// ChildSenderABI is the input ABI used to generate the binding from.
@@ -242,15 +244,15 @@ func (_ChildSender *ChildSenderTransactorSession) SendToRoot(amount *big.Int) (t
return _ChildSender.Contract.SendToRoot(&_ChildSender.TransactOpts, amount)
}
-// SendToRootParams is an auto generated read-only Go binding of transcaction calldata params
-type SendToRootParams struct {
+// ChildSenderSendToRootParams is an auto generated read-only Go binding of transcaction calldata params
+type ChildSenderSendToRootParams struct {
Param_amount *big.Int
}
// Parse SendToRoot method from calldata of a transaction
//
// Solidity: function sendToRoot(uint256 amount) returns()
-func ParseSendToRoot(calldata []byte) (*SendToRootParams, error) {
+func ParseChildSenderSendToRootParams(calldata []byte) (*ChildSenderSendToRootParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -265,7 +267,7 @@ func ParseSendToRoot(calldata []byte) (*SendToRootParams, error) {
return nil, fmt.Errorf("failed to unpack sendToRoot params data: %w", err)
}
- var paramsResult = new(SendToRootParams)
+ var paramsResult = new(ChildSenderSendToRootParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -274,7 +276,7 @@ func ParseSendToRoot(calldata []byte) (*SendToRootParams, error) {
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
- return &SendToRootParams{
+ return &ChildSenderSendToRootParams{
Param_amount: out0,
}, nil
}
@@ -352,6 +354,10 @@ type ChildSenderMessageSent struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_ChildSender *ChildSenderFilterer) MessageSentEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036")
+}
+
// FilterMessageSent is a free log retrieval operation binding the contract event 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036.
//
// Solidity: event MessageSent(bytes message)
diff --git a/cmd/devnet/contracts/gen_faucet.go b/cmd/devnet/contracts/gen_faucet.go
index fcd3741da20..69a3482bb68 100644
--- a/cmd/devnet/contracts/gen_faucet.go
+++ b/cmd/devnet/contracts/gen_faucet.go
@@ -1,4 +1,4 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// FaucetABI is the input ABI used to generate the binding from.
@@ -273,8 +275,8 @@ func (_Faucet *FaucetTransactorSession) Send(_destination libcommon.Address, _re
return _Faucet.Contract.Send(&_Faucet.TransactOpts, _destination, _requested)
}
-// SendParams is an auto generated read-only Go binding of transcaction calldata params
-type SendParams struct {
+// FaucetSendParams is an auto generated read-only Go binding of transcaction calldata params
+type FaucetSendParams struct {
Param__destination libcommon.Address
Param__requested *big.Int
}
@@ -282,7 +284,7 @@ type SendParams struct {
// Parse Send method from calldata of a transaction
//
// Solidity: function send(address _destination, uint256 _requested) payable returns()
-func ParseSend(calldata []byte) (*SendParams, error) {
+func ParseFaucetSendParams(calldata []byte) (*FaucetSendParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -297,7 +299,7 @@ func ParseSend(calldata []byte) (*SendParams, error) {
return nil, fmt.Errorf("failed to unpack send params data: %w", err)
}
- var paramsResult = new(SendParams)
+ var paramsResult = new(FaucetSendParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -307,7 +309,7 @@ func ParseSend(calldata []byte) (*SendParams, error) {
out0 := *abi.ConvertType(out[0], new(libcommon.Address)).(*libcommon.Address)
out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
- return &SendParams{
+ return &FaucetSendParams{
Param__destination: out0, Param__requested: out1,
}, nil
}
@@ -407,6 +409,10 @@ type FaucetReceived struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_Faucet *FaucetFilterer) ReceivedEventID() libcommon.Hash {
+ return libcommon.HexToHash("0xf11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef")
+}
+
// FilterReceived is a free log retrieval operation binding the contract event 0xf11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef.
//
// Solidity: event received(address _source, uint256 _amount)
@@ -542,6 +548,10 @@ type FaucetSent struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_Faucet *FaucetFilterer) SentEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x3bcb2e664d8f57273201bc888e82d6549f8308a52a9fcd7702b2ea8387f769a9")
+}
+
// FilterSent is a free log retrieval operation binding the contract event 0x3bcb2e664d8f57273201bc888e82d6549f8308a52a9fcd7702b2ea8387f769a9.
//
// Solidity: event sent(address _destination, uint256 _amount)
diff --git a/cmd/devnet/contracts/gen_rootreceiver.go b/cmd/devnet/contracts/gen_rootreceiver.go
index f7c12822f37..6c0a817a4e4 100644
--- a/cmd/devnet/contracts/gen_rootreceiver.go
+++ b/cmd/devnet/contracts/gen_rootreceiver.go
@@ -1,4 +1,4 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// RootReceiverABI is the input ABI used to generate the binding from.
@@ -335,15 +337,15 @@ func (_RootReceiver *RootReceiverTransactorSession) ReceiveMessage(inputData []b
return _RootReceiver.Contract.ReceiveMessage(&_RootReceiver.TransactOpts, inputData)
}
-// ReceiveMessageParams is an auto generated read-only Go binding of transcaction calldata params
-type ReceiveMessageParams struct {
+// RootReceiverReceiveMessageParams is an auto generated read-only Go binding of transcaction calldata params
+type RootReceiverReceiveMessageParams struct {
Param_inputData []byte
}
// Parse ReceiveMessage method from calldata of a transaction
//
// Solidity: function receiveMessage(bytes inputData) returns()
-func ParseReceiveMessage(calldata []byte) (*ReceiveMessageParams, error) {
+func ParseRootReceiverReceiveMessageParams(calldata []byte) (*RootReceiverReceiveMessageParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -358,7 +360,7 @@ func ParseReceiveMessage(calldata []byte) (*ReceiveMessageParams, error) {
return nil, fmt.Errorf("failed to unpack receiveMessage params data: %w", err)
}
- var paramsResult = new(ReceiveMessageParams)
+ var paramsResult = new(RootReceiverReceiveMessageParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -367,7 +369,7 @@ func ParseReceiveMessage(calldata []byte) (*ReceiveMessageParams, error) {
out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
- return &ReceiveMessageParams{
+ return &RootReceiverReceiveMessageParams{
Param_inputData: out0,
}, nil
}
@@ -446,6 +448,10 @@ type RootReceiverReceived struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_RootReceiver *RootReceiverFilterer) ReceivedEventID() libcommon.Hash {
+ return libcommon.HexToHash("0xf11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef")
+}
+
// FilterReceived is a free log retrieval operation binding the contract event 0xf11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef.
//
// Solidity: event received(address _source, uint256 _amount)
diff --git a/cmd/devnet/contracts/gen_rootsender.go b/cmd/devnet/contracts/gen_rootsender.go
index 5aba6c02b1c..3bdd34c1689 100644
--- a/cmd/devnet/contracts/gen_rootsender.go
+++ b/cmd/devnet/contracts/gen_rootsender.go
@@ -1,4 +1,4 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// RootSenderABI is the input ABI used to generate the binding from.
@@ -242,15 +244,15 @@ func (_RootSender *RootSenderTransactorSession) SendToChild(amount *big.Int) (ty
return _RootSender.Contract.SendToChild(&_RootSender.TransactOpts, amount)
}
-// SendToChildParams is an auto generated read-only Go binding of transcaction calldata params
-type SendToChildParams struct {
+// RootSenderSendToChildParams is an auto generated read-only Go binding of transcaction calldata params
+type RootSenderSendToChildParams struct {
Param_amount *big.Int
}
// Parse SendToChild method from calldata of a transaction
//
// Solidity: function sendToChild(uint256 amount) returns()
-func ParseSendToChild(calldata []byte) (*SendToChildParams, error) {
+func ParseRootSenderSendToChildParams(calldata []byte) (*RootSenderSendToChildParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -265,7 +267,7 @@ func ParseSendToChild(calldata []byte) (*SendToChildParams, error) {
return nil, fmt.Errorf("failed to unpack sendToChild params data: %w", err)
}
- var paramsResult = new(SendToChildParams)
+ var paramsResult = new(RootSenderSendToChildParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -274,7 +276,7 @@ func ParseSendToChild(calldata []byte) (*SendToChildParams, error) {
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
- return &SendToChildParams{
+ return &RootSenderSendToChildParams{
Param_amount: out0,
}, nil
}
diff --git a/cmd/devnet/contracts/gen_testrootchain.go b/cmd/devnet/contracts/gen_testrootchain.go
index b9150eb1f50..4ea3688cc20 100644
--- a/cmd/devnet/contracts/gen_testrootchain.go
+++ b/cmd/devnet/contracts/gen_testrootchain.go
@@ -1,4 +1,4 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// TestRootChainABI is the input ABI used to generate the binding from.
@@ -601,15 +603,15 @@ func (_TestRootChain *TestRootChainTransactorSession) UpdateDepositId(numDeposit
return _TestRootChain.Contract.UpdateDepositId(&_TestRootChain.TransactOpts, numDeposits)
}
-// SetHeimdallIdParams is an auto generated read-only Go binding of transcaction calldata params
-type SetHeimdallIdParams struct {
+// TestRootChainSetHeimdallIdParams is an auto generated read-only Go binding of transcaction calldata params
+type TestRootChainSetHeimdallIdParams struct {
Param__heimdallId string
}
// Parse SetHeimdallId method from calldata of a transaction
//
// Solidity: function setHeimdallId(string _heimdallId) returns()
-func ParseSetHeimdallId(calldata []byte) (*SetHeimdallIdParams, error) {
+func ParseTestRootChainSetHeimdallIdParams(calldata []byte) (*TestRootChainSetHeimdallIdParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -624,7 +626,7 @@ func ParseSetHeimdallId(calldata []byte) (*SetHeimdallIdParams, error) {
return nil, fmt.Errorf("failed to unpack setHeimdallId params data: %w", err)
}
- var paramsResult = new(SetHeimdallIdParams)
+ var paramsResult = new(TestRootChainSetHeimdallIdParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -633,20 +635,20 @@ func ParseSetHeimdallId(calldata []byte) (*SetHeimdallIdParams, error) {
out0 := *abi.ConvertType(out[0], new(string)).(*string)
- return &SetHeimdallIdParams{
+ return &TestRootChainSetHeimdallIdParams{
Param__heimdallId: out0,
}, nil
}
-// SetNextHeaderBlockParams is an auto generated read-only Go binding of transcaction calldata params
-type SetNextHeaderBlockParams struct {
+// TestRootChainSetNextHeaderBlockParams is an auto generated read-only Go binding of transcaction calldata params
+type TestRootChainSetNextHeaderBlockParams struct {
Param__value *big.Int
}
// Parse SetNextHeaderBlock method from calldata of a transaction
//
// Solidity: function setNextHeaderBlock(uint256 _value) returns()
-func ParseSetNextHeaderBlock(calldata []byte) (*SetNextHeaderBlockParams, error) {
+func ParseTestRootChainSetNextHeaderBlockParams(calldata []byte) (*TestRootChainSetNextHeaderBlockParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -661,7 +663,7 @@ func ParseSetNextHeaderBlock(calldata []byte) (*SetNextHeaderBlockParams, error)
return nil, fmt.Errorf("failed to unpack setNextHeaderBlock params data: %w", err)
}
- var paramsResult = new(SetNextHeaderBlockParams)
+ var paramsResult = new(TestRootChainSetNextHeaderBlockParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -670,13 +672,13 @@ func ParseSetNextHeaderBlock(calldata []byte) (*SetNextHeaderBlockParams, error)
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
- return &SetNextHeaderBlockParams{
+ return &TestRootChainSetNextHeaderBlockParams{
Param__value: out0,
}, nil
}
-// SubmitCheckpointParams is an auto generated read-only Go binding of transcaction calldata params
-type SubmitCheckpointParams struct {
+// TestRootChainSubmitCheckpointParams is an auto generated read-only Go binding of transcaction calldata params
+type TestRootChainSubmitCheckpointParams struct {
Param_data []byte
Param_arg1 [][3]*big.Int
}
@@ -684,7 +686,7 @@ type SubmitCheckpointParams struct {
// Parse SubmitCheckpoint method from calldata of a transaction
//
// Solidity: function submitCheckpoint(bytes data, uint256[3][] ) returns()
-func ParseSubmitCheckpoint(calldata []byte) (*SubmitCheckpointParams, error) {
+func ParseTestRootChainSubmitCheckpointParams(calldata []byte) (*TestRootChainSubmitCheckpointParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -699,7 +701,7 @@ func ParseSubmitCheckpoint(calldata []byte) (*SubmitCheckpointParams, error) {
return nil, fmt.Errorf("failed to unpack submitCheckpoint params data: %w", err)
}
- var paramsResult = new(SubmitCheckpointParams)
+ var paramsResult = new(TestRootChainSubmitCheckpointParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -709,20 +711,20 @@ func ParseSubmitCheckpoint(calldata []byte) (*SubmitCheckpointParams, error) {
out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
out1 := *abi.ConvertType(out[1], new([][3]*big.Int)).(*[][3]*big.Int)
- return &SubmitCheckpointParams{
+ return &TestRootChainSubmitCheckpointParams{
Param_data: out0, Param_arg1: out1,
}, nil
}
-// UpdateDepositIdParams is an auto generated read-only Go binding of transcaction calldata params
-type UpdateDepositIdParams struct {
+// TestRootChainUpdateDepositIdParams is an auto generated read-only Go binding of transcaction calldata params
+type TestRootChainUpdateDepositIdParams struct {
Param_numDeposits *big.Int
}
// Parse UpdateDepositId method from calldata of a transaction
//
// Solidity: function updateDepositId(uint256 numDeposits) returns(uint256 depositId)
-func ParseUpdateDepositId(calldata []byte) (*UpdateDepositIdParams, error) {
+func ParseTestRootChainUpdateDepositIdParams(calldata []byte) (*TestRootChainUpdateDepositIdParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -737,7 +739,7 @@ func ParseUpdateDepositId(calldata []byte) (*UpdateDepositIdParams, error) {
return nil, fmt.Errorf("failed to unpack updateDepositId params data: %w", err)
}
- var paramsResult = new(UpdateDepositIdParams)
+ var paramsResult = new(TestRootChainUpdateDepositIdParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -746,7 +748,7 @@ func ParseUpdateDepositId(calldata []byte) (*UpdateDepositIdParams, error) {
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
- return &UpdateDepositIdParams{
+ return &TestRootChainUpdateDepositIdParams{
Param_numDeposits: out0,
}, nil
}
@@ -829,6 +831,10 @@ type TestRootChainNewHeaderBlock struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_TestRootChain *TestRootChainFilterer) NewHeaderBlockEventID() libcommon.Hash {
+ return libcommon.HexToHash("0xba5de06d22af2685c6c7765f60067f7d2b08c2d29f53cdf14d67f6d1c9bfb527")
+}
+
// FilterNewHeaderBlock is a free log retrieval operation binding the contract event 0xba5de06d22af2685c6c7765f60067f7d2b08c2d29f53cdf14d67f6d1c9bfb527.
//
// Solidity: event NewHeaderBlock(address indexed proposer, uint256 indexed headerBlockId, uint256 indexed reward, uint256 start, uint256 end, bytes32 root)
@@ -990,6 +996,10 @@ type TestRootChainResetHeaderBlock struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_TestRootChain *TestRootChainFilterer) ResetHeaderBlockEventID() libcommon.Hash {
+ return libcommon.HexToHash("0xca1d8316287f938830e225956a7bb10fd5a1a1506dd2eb3a476751a488117205")
+}
+
// FilterResetHeaderBlock is a free log retrieval operation binding the contract event 0xca1d8316287f938830e225956a7bb10fd5a1a1506dd2eb3a476751a488117205.
//
// Solidity: event ResetHeaderBlock(address indexed proposer, uint256 indexed headerBlockId)
diff --git a/cmd/devnet/contracts/gen_teststatesender.go b/cmd/devnet/contracts/gen_teststatesender.go
index eb18a91b283..b64c9971c6c 100644
--- a/cmd/devnet/contracts/gen_teststatesender.go
+++ b/cmd/devnet/contracts/gen_teststatesender.go
@@ -1,4 +1,4 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// TestStateSenderABI is the input ABI used to generate the binding from.
@@ -294,8 +296,8 @@ func (_TestStateSender *TestStateSenderTransactorSession) SyncState(receiver lib
return _TestStateSender.Contract.SyncState(&_TestStateSender.TransactOpts, receiver, data)
}
-// RegisterParams is an auto generated read-only Go binding of transcaction calldata params
-type RegisterParams struct {
+// TestStateSenderRegisterParams is an auto generated read-only Go binding of transcaction calldata params
+type TestStateSenderRegisterParams struct {
Param_sender libcommon.Address
Param_receiver libcommon.Address
}
@@ -303,7 +305,7 @@ type RegisterParams struct {
// Parse Register method from calldata of a transaction
//
// Solidity: function register(address sender, address receiver) returns()
-func ParseRegister(calldata []byte) (*RegisterParams, error) {
+func ParseTestStateSenderRegisterParams(calldata []byte) (*TestStateSenderRegisterParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -318,7 +320,7 @@ func ParseRegister(calldata []byte) (*RegisterParams, error) {
return nil, fmt.Errorf("failed to unpack register params data: %w", err)
}
- var paramsResult = new(RegisterParams)
+ var paramsResult = new(TestStateSenderRegisterParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -328,13 +330,13 @@ func ParseRegister(calldata []byte) (*RegisterParams, error) {
out0 := *abi.ConvertType(out[0], new(libcommon.Address)).(*libcommon.Address)
out1 := *abi.ConvertType(out[1], new(libcommon.Address)).(*libcommon.Address)
- return &RegisterParams{
+ return &TestStateSenderRegisterParams{
Param_sender: out0, Param_receiver: out1,
}, nil
}
-// SyncStateParams is an auto generated read-only Go binding of transcaction calldata params
-type SyncStateParams struct {
+// TestStateSenderSyncStateParams is an auto generated read-only Go binding of transcaction calldata params
+type TestStateSenderSyncStateParams struct {
Param_receiver libcommon.Address
Param_data []byte
}
@@ -342,7 +344,7 @@ type SyncStateParams struct {
// Parse SyncState method from calldata of a transaction
//
// Solidity: function syncState(address receiver, bytes data) returns()
-func ParseSyncState(calldata []byte) (*SyncStateParams, error) {
+func ParseTestStateSenderSyncStateParams(calldata []byte) (*TestStateSenderSyncStateParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -357,7 +359,7 @@ func ParseSyncState(calldata []byte) (*SyncStateParams, error) {
return nil, fmt.Errorf("failed to unpack syncState params data: %w", err)
}
- var paramsResult = new(SyncStateParams)
+ var paramsResult = new(TestStateSenderSyncStateParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -367,7 +369,7 @@ func ParseSyncState(calldata []byte) (*SyncStateParams, error) {
out0 := *abi.ConvertType(out[0], new(libcommon.Address)).(*libcommon.Address)
out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
- return &SyncStateParams{
+ return &TestStateSenderSyncStateParams{
Param_receiver: out0, Param_data: out1,
}, nil
}
@@ -447,6 +449,10 @@ type TestStateSenderNewRegistration struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_TestStateSender *TestStateSenderFilterer) NewRegistrationEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x3f4512aacd7a664fdb321a48e8340120d63253a91c6367a143abd19ecf68aedd")
+}
+
// FilterNewRegistration is a free log retrieval operation binding the contract event 0x3f4512aacd7a664fdb321a48e8340120d63253a91c6367a143abd19ecf68aedd.
//
// Solidity: event NewRegistration(address indexed user, address indexed sender, address indexed receiver)
@@ -609,6 +615,10 @@ type TestStateSenderRegistrationUpdated struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_TestStateSender *TestStateSenderFilterer) RegistrationUpdatedEventID() libcommon.Hash {
+ return libcommon.HexToHash("0xc51cb1a93ec91e927852b3445875ec77b148271953e5c0b43698c968ad6fc47d")
+}
+
// FilterRegistrationUpdated is a free log retrieval operation binding the contract event 0xc51cb1a93ec91e927852b3445875ec77b148271953e5c0b43698c968ad6fc47d.
//
// Solidity: event RegistrationUpdated(address indexed user, address indexed sender, address indexed receiver)
@@ -771,6 +781,10 @@ type TestStateSenderStateSynced struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_TestStateSender *TestStateSenderFilterer) StateSyncedEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x103fed9db65eac19c4d870f49ab7520fe03b99f1838e5996caf47e9e43308392")
+}
+
// FilterStateSynced is a free log retrieval operation binding the contract event 0x103fed9db65eac19c4d870f49ab7520fe03b99f1838e5996caf47e9e43308392.
//
// Solidity: event StateSynced(uint256 indexed id, address indexed contractAddress, bytes data)
diff --git a/cmd/diag/downloader/diag_downloader.go b/cmd/diag/downloader/diag_downloader.go
index 3e5577c4073..cc50a46636c 100644
--- a/cmd/diag/downloader/diag_downloader.go
+++ b/cmd/diag/downloader/diag_downloader.go
@@ -34,7 +34,7 @@ var (
FileFilterFlag = cli.StringFlag{
Name: "downloader.file.filter",
Aliases: []string{"dff"},
- Usage: "Filter files list [all|active|inactive|downloaded|queued], dafault value is all",
+ Usage: "Filter files list [all|active|inactive|downloaded|queued], default value is all",
Required: false,
Value: "all",
}
diff --git a/cmd/evm/internal/t8ntool/gen_stenv.go b/cmd/evm/internal/t8ntool/gen_stenv.go
index c47122401a6..a7dc4fc02ab 100644
--- a/cmd/evm/internal/t8ntool/gen_stenv.go
+++ b/cmd/evm/internal/t8ntool/gen_stenv.go
@@ -9,7 +9,6 @@ import (
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/math"
- common0 "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
)
@@ -18,7 +17,7 @@ var _ = (*stEnvMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (s stEnv) MarshalJSON() ([]byte, error) {
type stEnv struct {
- Coinbase common0.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
+ Coinbase common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"currentDifficulty"`
Random *math.HexOrDecimal256 `json:"currentRandom"`
MixDigest common.Hash `json:"mixHash,omitempty"`
@@ -37,7 +36,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
RequestsHash *common.Hash `json:"requestsHash,omitempty"`
}
var enc stEnv
- enc.Coinbase = common0.UnprefixedAddress(s.Coinbase)
+ enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
enc.Difficulty = (*math.HexOrDecimal256)(s.Difficulty)
enc.Random = (*math.HexOrDecimal256)(s.Random)
enc.MixDigest = s.MixDigest
@@ -60,7 +59,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
// UnmarshalJSON unmarshals from JSON.
func (s *stEnv) UnmarshalJSON(input []byte) error {
type stEnv struct {
- Coinbase *common0.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
+ Coinbase *common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"currentDifficulty"`
Random *math.HexOrDecimal256 `json:"currentRandom"`
MixDigest *common.Hash `json:"mixHash,omitempty"`
diff --git a/cmd/pics/contracts/gen_token.go b/cmd/pics/contracts/gen_token.go
index 124fcb5f587..e12ee0af782 100644
--- a/cmd/pics/contracts/gen_token.go
+++ b/cmd/pics/contracts/gen_token.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// TokenABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployToken(auth *bind.TransactOpts, backend bind.ContractBackend, _minter
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TokenBin), backend, _minter)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(TokenBin), backend, _minter)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
@@ -324,3 +326,81 @@ func (_Token *TokenSession) Transfer(_to libcommon.Address, _value *big.Int) (ty
func (_Token *TokenTransactorSession) Transfer(_to libcommon.Address, _value *big.Int) (types.Transaction, error) {
return _Token.Contract.Transfer(&_Token.TransactOpts, _to, _value)
}
+
+// TokenMintParams is an auto generated read-only Go binding of transcaction calldata params
+type TokenMintParams struct {
+ Param__to libcommon.Address
+ Param__value *big.Int
+}
+
+// Parse Mint method from calldata of a transaction
+//
+// Solidity: function mint(address _to, uint256 _value) returns(bool)
+func ParseTokenMintParams(calldata []byte) (*TokenMintParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TokenABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["mint"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack mint params data: %w", err)
+ }
+
+ var paramsResult = new(TokenMintParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(libcommon.Address)).(*libcommon.Address)
+ out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+
+ return &TokenMintParams{
+ Param__to: out0, Param__value: out1,
+ }, nil
+}
+
+// TokenTransferParams is an auto generated read-only Go binding of transcaction calldata params
+type TokenTransferParams struct {
+ Param__to libcommon.Address
+ Param__value *big.Int
+}
+
+// Parse Transfer method from calldata of a transaction
+//
+// Solidity: function transfer(address _to, uint256 _value) returns(bool)
+func ParseTokenTransferParams(calldata []byte) (*TokenTransferParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TokenABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["transfer"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack transfer params data: %w", err)
+ }
+
+ var paramsResult = new(TokenTransferParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(libcommon.Address)).(*libcommon.Address)
+ out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+
+ return &TokenTransferParams{
+ Param__to: out0, Param__value: out1,
+ }, nil
+}
diff --git a/cmd/rpcdaemon/rpcservices/eth_backend.go b/cmd/rpcdaemon/rpcservices/eth_backend.go
index 68e06fabe83..8598411befd 100644
--- a/cmd/rpcdaemon/rpcservices/eth_backend.go
+++ b/cmd/rpcdaemon/rpcservices/eth_backend.go
@@ -282,7 +282,7 @@ func (back *RemoteBackend) SubscribeLogs(ctx context.Context, onNewLogs func(rep
return nil
}
-func (back *RemoteBackend) TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (uint64, bool, error) {
+func (back *RemoteBackend) TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (uint64, uint64, bool, error) {
return back.blockReader.TxnLookup(ctx, tx, txnHash)
}
func (back *RemoteBackend) HasSenders(ctx context.Context, tx kv.Getter, hash common.Hash, blockNum uint64) (bool, error) {
diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go
index 0f2c8cea5ee..a5133f2a46c 100644
--- a/cmd/state/commands/opcode_tracer.go
+++ b/cmd/state/commands/opcode_tracer.go
@@ -736,7 +736,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta
usedGas := new(uint64)
usedBlobGas := new(uint64)
var receipts types.Receipts
- core.InitializeBlockExecution(engine, nil, header, chainConfig, ibs, logger, nil)
+ core.InitializeBlockExecution(engine, nil, header, chainConfig, ibs, nil, logger, nil)
rules := chainConfig.Rules(block.NumberU64(), block.Time())
for i, txn := range block.Transactions() {
ibs.SetTxContext(i)
diff --git a/cmd/state/exec3/state.go b/cmd/state/exec3/state.go
index 65f570e14bb..a439c7cd1e8 100644
--- a/cmd/state/exec3/state.go
+++ b/cmd/state/exec3/state.go
@@ -132,6 +132,7 @@ func (rw *Worker) ResetTx(chainTx kv.Tx) {
func (rw *Worker) Run() error {
for txTask, ok := rw.in.Next(rw.ctx); ok; txTask, ok = rw.in.Next(rw.ctx) {
+ //fmt.Println("RTX", txTask.BlockNum, txTask.TxIndex, txTask.TxNum, txTask.Final)
rw.RunTxTask(txTask, rw.isMining)
if err := rw.resultCh.Add(rw.ctx, txTask); err != nil {
return err
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 88c3a71b8a2..b6e63c7e184 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -868,7 +868,7 @@ var (
Value: cli.NewStringSlice(),
}
CaplinSubscribeAllTopicsFlag = cli.BoolFlag{
- Name: "caplin.subscibe-all-topics",
+ Name: "caplin.subscribe-all-topics",
Usage: "Subscribe to all gossip topics",
Value: false,
}
@@ -885,7 +885,7 @@ var (
CaplinMaxPeerCount = cli.Uint64Flag{
Name: "caplin.max-peer-count",
Usage: "Max number of peers to connect",
- Value: 64,
+ Value: 80,
}
SentinelAddrFlag = cli.StringFlag{
diff --git a/consensus/aura/auraabi/gen_block_reward.go b/consensus/aura/auraabi/gen_block_reward.go
index 0b1918fd00c..48b3e61129e 100644
--- a/consensus/aura/auraabi/gen_block_reward.go
+++ b/consensus/aura/auraabi/gen_block_reward.go
@@ -1,14 +1,13 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package auraabi
import (
- "math/big"
- "strings"
-
"fmt"
+ "math/big"
"reflect"
+ "strings"
ethereum "github.com/erigontech/erigon"
libcommon "github.com/erigontech/erigon-lib/common"
@@ -27,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// BlockRewardABI is the input ABI used to generate the binding from.
@@ -195,8 +196,8 @@ func (_BlockReward *BlockRewardTransactorSession) Reward(benefactors []libcommon
return _BlockReward.Contract.Reward(&_BlockReward.TransactOpts, benefactors, kind)
}
-// RewardParams is an auto generated read-only Go binding of transcaction calldata params
-type RewardParams struct {
+// BlockRewardRewardParams is an auto generated read-only Go binding of transcaction calldata params
+type BlockRewardRewardParams struct {
Param_benefactors []libcommon.Address
Param_kind []uint16
}
@@ -204,7 +205,7 @@ type RewardParams struct {
// Parse Reward method from calldata of a transaction
//
// Solidity: function reward(address[] benefactors, uint16[] kind) returns(address[], uint256[])
-func ParseReward(calldata []byte) (*RewardParams, error) {
+func ParseBlockRewardRewardParams(calldata []byte) (*BlockRewardRewardParams, error) {
if len(calldata) <= 4 {
return nil, fmt.Errorf("invalid calldata input")
}
@@ -219,7 +220,7 @@ func ParseReward(calldata []byte) (*RewardParams, error) {
return nil, fmt.Errorf("failed to unpack reward params data: %w", err)
}
- var paramsResult = new(RewardParams)
+ var paramsResult = new(BlockRewardRewardParams)
value := reflect.ValueOf(paramsResult).Elem()
if value.NumField() != len(out) {
@@ -229,7 +230,7 @@ func ParseReward(calldata []byte) (*RewardParams, error) {
out0 := *abi.ConvertType(out[0], new([]libcommon.Address)).(*[]libcommon.Address)
out1 := *abi.ConvertType(out[1], new([]uint16)).(*[]uint16)
- return &RewardParams{
+ return &BlockRewardRewardParams{
Param_benefactors: out0, Param_kind: out1,
}, nil
}
diff --git a/consensus/aura/auraabi/gen_validator_set.go b/consensus/aura/auraabi/gen_validator_set.go
index 4e73d18f816..42fdbacb6f5 100644
--- a/consensus/aura/auraabi/gen_validator_set.go
+++ b/consensus/aura/auraabi/gen_validator_set.go
@@ -1,10 +1,12 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package auraabi
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
ethereum "github.com/erigontech/erigon"
@@ -24,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// ValidatorSetABI is the input ABI used to generate the binding from.
@@ -380,6 +384,10 @@ type ValidatorSetInitiateChange struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_ValidatorSet *ValidatorSetFilterer) InitiateChangeEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89")
+}
+
// FilterInitiateChange is a free log retrieval operation binding the contract event 0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89.
//
// Solidity: event InitiateChange(bytes32 indexed _parent_hash, address[] _new_set)
diff --git a/consensus/consensus.go b/consensus/consensus.go
index 0429f57e335..0ed3552cfbd 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -205,9 +205,12 @@ type PoW interface {
}
// Transfer subtracts amount from sender and adds amount to recipient using the given Db
-func Transfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) {
+func Transfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) error {
if !bailout {
- db.SubBalance(sender, amount, tracing.BalanceChangeTransfer)
+ err := db.SubBalance(sender, amount, tracing.BalanceChangeTransfer)
+ if err != nil {
+ return err
+ }
}
- db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer)
+ return db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer)
}
diff --git a/consensus/misc/dao.go b/consensus/misc/dao.go
index fd02f56bfdc..c5671bb08b6 100644
--- a/consensus/misc/dao.go
+++ b/consensus/misc/dao.go
@@ -73,15 +73,24 @@ func VerifyDAOHeaderExtraData(config *chain.Config, header *types.Header) error
// ApplyDAOHardFork modifies the state database according to the DAO hard-fork
// rules, transferring all balances of a set of DAO accounts to a single refund
// contract.
-func ApplyDAOHardFork(statedb *state.IntraBlockState) {
+func ApplyDAOHardFork(statedb *state.IntraBlockState) error {
// Retrieve the contract to refund balances into
- if !statedb.Exist(params.DAORefundContract) {
+ exist, err := statedb.Exist(params.DAORefundContract)
+ if err != nil {
+ return err
+ }
+ if !exist {
statedb.CreateAccount(params.DAORefundContract, false)
}
// Move every DAO account and extra-balance account funds into the refund contract
for _, addr := range params.DAODrainList() {
- statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), tracing.BalanceIncreaseDaoContract)
+ balance, err := statedb.GetBalance(addr)
+ if err != nil {
+ return err
+ }
+ statedb.AddBalance(params.DAORefundContract, balance, tracing.BalanceIncreaseDaoContract)
statedb.SetBalance(addr, new(uint256.Int), tracing.BalanceDecreaseDaoAccount)
}
+ return nil
}
diff --git a/consensus/misc/eip2935.go b/consensus/misc/eip2935.go
index 460c95f4b39..de3078e0a34 100644
--- a/consensus/misc/eip2935.go
+++ b/consensus/misc/eip2935.go
@@ -29,21 +29,25 @@ import (
"github.com/erigontech/erigon/params"
)
-func StoreBlockHashesEip2935(header *types.Header, state *state.IntraBlockState, config *chain.Config, headerReader consensus.ChainHeaderReader) {
- if state.GetCodeSize(params.HistoryStorageAddress) == 0 {
+func StoreBlockHashesEip2935(header *types.Header, state *state.IntraBlockState, config *chain.Config, headerReader consensus.ChainHeaderReader) error {
+ codeSize, err := state.GetCodeSize(params.HistoryStorageAddress)
+ if err != nil {
+ return err
+ }
+ if codeSize == 0 {
log.Debug("[EIP-2935] No code deployed to HistoryStorageAddress before call to store EIP-2935 history")
- return
+ return nil
}
headerNum := header.Number.Uint64()
if headerNum == 0 { // Activation of fork at Genesis
- return
+ return nil
}
- storeHash(headerNum-1, header.ParentHash, state)
+ return storeHash(headerNum-1, header.ParentHash, state)
}
-func storeHash(num uint64, hash libcommon.Hash, state *state.IntraBlockState) {
+func storeHash(num uint64, hash libcommon.Hash, state *state.IntraBlockState) error {
slotNum := num % params.BlockHashHistoryServeWindow
storageSlot := libcommon.BytesToHash(uint256.NewInt(slotNum).Bytes())
parentHashInt := uint256.NewInt(0).SetBytes32(hash.Bytes())
- state.SetState(params.HistoryStorageAddress, &storageSlot, *parentHashInt)
+ return state.SetState(params.HistoryStorageAddress, &storageSlot, *parentHashInt)
}
diff --git a/core/blockchain.go b/core/blockchain.go
index 8d86276b636..d34605b3104 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -103,14 +103,14 @@ func ExecuteBlockEphemerally(
gp.AddGas(block.GasLimit()).AddBlobGas(chainConfig.GetMaxBlobGasPerBlock())
// TODO: send the new tracer once we switch to the tracing.Hook
- if err := InitializeBlockExecution(engine, chainReader, block.Header(), chainConfig, ibs, logger, nil); err != nil {
+ if err := InitializeBlockExecution(engine, chainReader, block.Header(), chainConfig, ibs, stateWriter, logger, nil); err != nil {
return nil, err
}
var rejectedTxs []*RejectedTx
includedTxs := make(types.Transactions, 0, block.Transactions().Len())
receipts := make(types.Receipts, 0, block.Transactions().Len())
- noop := state.NewNoopWriter()
+ // noop := state.NewNoopWriter()
for i, txn := range block.Transactions() {
ibs.SetTxContext(i)
writeTrace := false
@@ -122,7 +122,7 @@ func ExecuteBlockEphemerally(
vmConfig.Tracer = tracer
writeTrace = true
}
- receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, txn, usedGas, usedBlobGas, *vmConfig)
+ receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, stateWriter, header, txn, usedGas, usedBlobGas, *vmConfig)
if writeTrace {
if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok {
ftracer.Flush(txn)
@@ -167,15 +167,19 @@ func ExecuteBlockEphemerally(
return nil, fmt.Errorf("bloom computed by execution: %x, in header: %x", bloom, header.Bloom)
}
}
-
+ var newBlock *types.Block
+ var err error
if !vmConfig.ReadOnly {
txs := block.Transactions()
- if _, _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), chainReader, false, logger); err != nil {
+ newBlock, _, _, _, err = FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), chainReader, true, logger)
+ if err != nil {
return nil, err
}
}
blockLogs := ibs.Logs()
+ newRoot := newBlock.Root()
execRs := &EphemeralExecResult{
+ StateRoot: newRoot,
TxRoot: types.DeriveSha(includedTxs),
ReceiptRoot: receiptSha,
Bloom: bloom,
@@ -353,13 +357,15 @@ func FinalizeBlockExecution(
}
func InitializeBlockExecution(engine consensus.Engine, chain consensus.ChainHeaderReader, header *types.Header,
- cc *chain.Config, ibs *state.IntraBlockState, logger log.Logger, tracer *tracing.Hooks,
+ cc *chain.Config, ibs *state.IntraBlockState, stateWriter state.StateWriter, logger log.Logger, tracer *tracing.Hooks,
) error {
engine.Initialize(cc, chain, header, ibs, func(contract libcommon.Address, data []byte, ibState *state.IntraBlockState, header *types.Header, constCall bool) ([]byte, error) {
return SysCallContract(contract, data, cc, ibState, header, engine, constCall)
}, logger, tracer)
- noop := state.NewNoopWriter()
- ibs.FinalizeTx(cc.Rules(header.Number.Uint64(), header.Time), noop)
+ if stateWriter == nil {
+ stateWriter = state.NewNoopWriter()
+ }
+ ibs.FinalizeTx(cc.Rules(header.Number.Uint64(), header.Time), stateWriter)
return nil
}
diff --git a/core/chain_makers.go b/core/chain_makers.go
index b2c50c9de7d..778ba06009f 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -176,10 +176,18 @@ func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) {
// TxNonce returns the next valid transaction nonce for the
// account at addr. It panics if the account does not exist.
func (b *BlockGen) TxNonce(addr libcommon.Address) uint64 {
- if !b.ibs.Exist(addr) {
+ exist, err := b.ibs.Exist(addr)
+ if err != nil {
+ panic(fmt.Sprintf("can't get account: %s", err))
+ }
+ if !exist {
panic("account does not exist")
}
- return b.ibs.GetNonce(addr)
+ nonce, err := b.ibs.GetNonce(addr)
+ if err != nil {
+ panic(fmt.Sprintf("can't get account: %s", err))
+ }
+ return nonce
}
// AddUncle adds an uncle header to the generated block.
@@ -358,7 +366,7 @@ func GenerateChain(config *chain.Config, parent *types.Block, engine consensus.E
}
}
if b.engine != nil {
- err := InitializeBlockExecution(b.engine, nil, b.header, config, ibs, logger, nil)
+ err := InitializeBlockExecution(b.engine, nil, b.header, config, ibs, nil, logger, nil)
if err != nil {
return nil, nil, fmt.Errorf("call to InitializeBlockExecution: %w", err)
}
diff --git a/core/evm.go b/core/evm.go
index 34dcd500316..2f6dc320a5d 100644
--- a/core/evm.go
+++ b/core/evm.go
@@ -138,6 +138,10 @@ func GetHashFn(ref *types.Header, getHeader func(hash libcommon.Hash, number uin
// CanTransfer checks whether there are enough funds in the address' account to make a transfer.
// This does not take the necessary gas in to account to make the transfer valid.
-func CanTransfer(db evmtypes.IntraBlockState, addr libcommon.Address, amount *uint256.Int) bool {
- return !db.GetBalance(addr).Lt(amount)
+func CanTransfer(db evmtypes.IntraBlockState, addr libcommon.Address, amount *uint256.Int) (bool, error) {
+ balance, err := db.GetBalance(addr)
+ if err != nil {
+ return false, err
+ }
+ return !balance.Lt(amount), nil
}
diff --git a/core/genesis_test.go b/core/genesis_test.go
index 8a340a7e3ef..262382a64ec 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -154,9 +154,11 @@ func TestAllocConstructor(t *testing.T) {
reader, err := rpchelper.CreateHistoryStateReader(tx, rawdbv3.TxNums, 1, 0, genSpec.Config.ChainName)
require.NoError(err)
state := state.New(reader)
- balance := state.GetBalance(address)
+ balance, err := state.GetBalance(address)
+ assert.NoError(err)
assert.Equal(funds, balance.ToBig())
- code := state.GetCode(address)
+ code, err := state.GetCode(address)
+ assert.NoError(err)
assert.Equal(libcommon.FromHex("5f355f55"), code)
key0 := libcommon.HexToHash("0000000000000000000000000000000000000000000000000000000000000000")
diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go
index cc672a33fe8..c1b5175cb46 100644
--- a/core/rawdb/accessors_indexes.go
+++ b/core/rawdb/accessors_indexes.go
@@ -20,8 +20,7 @@
package rawdb
import (
- "math/big"
-
+ "encoding/binary"
libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon-lib/log/v3"
@@ -39,23 +38,28 @@ type TxLookupEntry struct {
// ReadTxLookupEntry retrieves the positional metadata associated with a transaction
// hash to allow retrieving the transaction or receipt by hash.
-func ReadTxLookupEntry(db kv.Getter, txnHash libcommon.Hash) (*uint64, error) {
+func ReadTxLookupEntry(db kv.Getter, txnHash libcommon.Hash) (blockNumber *uint64, txNum *uint64, err error) {
data, err := db.GetOne(kv.TxLookup, txnHash.Bytes())
if err != nil {
- return nil, err
+ return nil, nil, err
}
- if len(data) == 0 {
- return nil, nil
+ if len(data) != 16 {
+ return nil, nil, nil
}
- number := new(big.Int).SetBytes(data).Uint64()
- return &number, nil
+ numberBlockNum := binary.BigEndian.Uint64(data[:8])
+ numberTxNum := binary.BigEndian.Uint64(data[8:]) + 1
+
+ return &numberBlockNum, &numberTxNum, nil
}
// WriteTxLookupEntries stores a positional metadata for every transaction from
// a block, enabling hash based transaction and receipt lookups.
-func WriteTxLookupEntries(db kv.Putter, block *types.Block) {
- for _, txn := range block.Transactions() {
- data := block.Number().Bytes()
+func WriteTxLookupEntries(db kv.Putter, block *types.Block, txNum uint64) {
+ data := make([]byte, 16)
+ for i, txn := range block.Transactions() {
+ binary.BigEndian.PutUint64(data[:8], block.NumberU64())
+ binary.BigEndian.PutUint64(data[8:], txNum+uint64(i)+1)
+
if err := db.Put(kv.TxLookup, txn.Hash().Bytes(), data); err != nil {
log.Crit("Failed to store transaction lookup entry", "err", err)
}
diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go
index 8dd02b14a13..a0ba8bb95f4 100644
--- a/core/rawdb/accessors_indexes_test.go
+++ b/core/rawdb/accessors_indexes_test.go
@@ -29,6 +29,7 @@ import (
libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/kv"
+ "github.com/erigontech/erigon-lib/kv/rawdbv3"
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/core/rawdb"
"github.com/erigontech/erigon/core/types"
@@ -41,12 +42,12 @@ func TestLookupStorage(t *testing.T) {
t.Parallel()
tests := []struct {
name string
- writeTxLookupEntries func(kv.Putter, *types.Block)
+ writeTxLookupEntries func(kv.Putter, *types.Block, uint64)
}{
{
"DatabaseV6",
- func(db kv.Putter, block *types.Block) {
- rawdb.WriteTxLookupEntries(db, block)
+ func(db kv.Putter, block *types.Block, txNum uint64) {
+ rawdb.WriteTxLookupEntries(db, block, txNum)
},
},
// Erigon: older databases are removed, no backward compatibility
@@ -71,7 +72,7 @@ func TestLookupStorage(t *testing.T) {
// Check that no transactions entries are in a pristine database
for i, txn := range txs {
- if txn2, _, _, _, _ := readTransactionByHash(tx, txn.Hash(), br); txn2 != nil {
+ if txn2, _, _, _, _, _ := readTransactionByHash(tx, txn.Hash(), br); txn2 != nil {
t.Fatalf("txn #%d [%x]: non existent transaction returned: %v", i, txn.Hash(), txn2)
}
}
@@ -85,18 +86,26 @@ func TestLookupStorage(t *testing.T) {
if err := rawdb.WriteSenders(tx, block.Hash(), block.NumberU64(), block.Body().SendersFromTxs()); err != nil {
t.Fatal(err)
}
- tc.writeTxLookupEntries(tx, block)
+ txNumMin, err := rawdbv3.TxNums.Min(tx, block.NumberU64())
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ tc.writeTxLookupEntries(tx, block, txNumMin)
for i, txn := range txs {
- if txn2, hash, number, index, _ := readTransactionByHash(tx, txn.Hash(), br); txn2 == nil {
+ if txn2, hash, blockNumber, txNum, index, _ := readTransactionByHash(tx, txn.Hash(), br); txn2 == nil {
t.Fatalf("txn #%d [%x]: transaction not found", i, txn.Hash())
} else {
- if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) {
- t.Fatalf("txn #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, txn.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i)
+ if hash != block.Hash() || blockNumber != block.NumberU64() || index != uint64(i) {
+ t.Fatalf("txn #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, txn.Hash(), hash, blockNumber, index, block.Hash(), block.NumberU64(), i)
}
if txn.Hash() != txn2.Hash() {
t.Fatalf("txn #%d [%x]: transaction mismatch: have %v, want %v", i, txn.Hash(), txn, txn2)
}
+ if txNum != txNumMin+uint64(i)+2 {
+ t.Fatalf("txn #%d [%x]: txnum mismatch: have %d, want %d", i, txn.Hash(), txNum, txNumMin+uint64(i)+1)
+ }
}
}
// Delete the transactions and check purge
@@ -104,7 +113,7 @@ func TestLookupStorage(t *testing.T) {
if err := rawdb.DeleteTxLookupEntry(tx, txn.Hash()); err != nil {
t.Fatal(err)
}
- if txn2, _, _, _, _ := readTransactionByHash(tx, txn.Hash(), br); txn2 != nil {
+ if txn2, _, _, _, _, _ := readTransactionByHash(tx, txn.Hash(), br); txn2 != nil {
t.Fatalf("txn #%d [%x]: deleted transaction returned: %v", i, txn.Hash(), txn2)
}
}
@@ -114,36 +123,41 @@ func TestLookupStorage(t *testing.T) {
// ReadTransactionByHash retrieves a specific transaction from the database, along with
// its added positional metadata.
-func readTransactionByHash(db kv.Tx, hash libcommon.Hash, br services.FullBlockReader) (types.Transaction, libcommon.Hash, uint64, uint64, error) {
- blockNumber, err := rawdb.ReadTxLookupEntry(db, hash)
+func readTransactionByHash(db kv.Tx, hash libcommon.Hash, br services.FullBlockReader) (txn types.Transaction, blockHash libcommon.Hash, blockNumber uint64, txNum uint64, txIndex uint64, err error) {
+ blockNumberPtr, txNumPtr, err := rawdb.ReadTxLookupEntry(db, hash)
if err != nil {
- return nil, libcommon.Hash{}, 0, 0, err
+ return nil, libcommon.Hash{}, 0, 0, 0, err
+ }
+ if blockNumberPtr == nil {
+ return nil, libcommon.Hash{}, 0, 0, 0, nil
}
- if blockNumber == nil {
- return nil, libcommon.Hash{}, 0, 0, nil
+ blockNumber = *blockNumberPtr
+ if txNumPtr == nil {
+ return nil, libcommon.Hash{}, 0, 0, 0, nil
}
- blockHash, ok, err := br.CanonicalHash(context.Background(), db, *blockNumber)
+ txNum = *txNumPtr
+ blockHash, ok, err := br.CanonicalHash(context.Background(), db, blockNumber)
if err != nil {
- return nil, libcommon.Hash{}, 0, 0, err
+ return nil, libcommon.Hash{}, 0, 0, 0, err
}
if !ok || blockHash == (libcommon.Hash{}) {
- return nil, libcommon.Hash{}, 0, 0, nil
+ return nil, libcommon.Hash{}, 0, 0, 0, nil
}
- body, _ := br.BodyWithTransactions(context.Background(), db, blockHash, *blockNumber)
+ body, _ := br.BodyWithTransactions(context.Background(), db, blockHash, blockNumber)
if body == nil {
log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash)
- return nil, libcommon.Hash{}, 0, 0, nil
+ return nil, libcommon.Hash{}, 0, 0, 0, nil
}
- senders, err1 := rawdb.ReadSenders(db, blockHash, *blockNumber)
+ senders, err1 := rawdb.ReadSenders(db, blockHash, blockNumber)
if err1 != nil {
- return nil, libcommon.Hash{}, 0, 0, err1
+ return nil, libcommon.Hash{}, 0, 0, 0, err1
}
body.SendersToTxs(senders)
- for txIndex, txn := range body.Transactions {
- if txn.Hash() == hash {
- return txn, blockHash, *blockNumber, uint64(txIndex), nil
+ for txInd, txnValue := range body.Transactions {
+ if txnValue.Hash() == hash {
+ return txnValue, blockHash, blockNumber, txNum, uint64(txInd), nil
}
}
log.Error("Transaction not found", "number", blockNumber, "hash", blockHash, "txhash", hash)
- return nil, libcommon.Hash{}, 0, 0, nil
+ return nil, libcommon.Hash{}, 0, 0, 0, nil
}
diff --git a/core/state/contracts/gen.go b/core/state/contracts/gen.go
index a8acdf7cd65..059acc37f11 100644
--- a/core/state/contracts/gen.go
+++ b/core/state/contracts/gen.go
@@ -31,3 +31,8 @@ package contracts
// poly.sol
//go:generate solc --allow-paths ., --abi --bin --overwrite --optimize -o build poly.sol
//go:generate abigen -abi build/Poly.abi -bin build/Poly.bin -pkg contracts -type poly -out ./gen_poly.go
+
+// revive2.sol
+//go:generate solc --allow-paths ., --abi --bin --overwrite --optimize -o build revive2.sol
+//go:generate abigen -abi build/Revive2.abi -bin build/Revive2.bin -pkg contracts -type revive2 -out ./gen_revive2.go
+//go:generate abigen -abi build/Phoenix.abi -bin build/Phoenix.bin -pkg contracts -type phoenix -out ./gen_phoenix.go
diff --git a/core/state/contracts/gen_changer.go b/core/state/contracts/gen_changer.go
index 26e66ba0adc..a33f61616cd 100644
--- a/core/state/contracts/gen_changer.go
+++ b/core/state/contracts/gen_changer.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// ChangerABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployChanger(auth *bind.TransactOpts, backend bind.ContractBackend) (libco
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ChangerBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(ChangerBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
diff --git a/core/state/contracts/gen_phoenix.go b/core/state/contracts/gen_phoenix.go
index 9ba545f3357..91265f207d6 100644
--- a/core/state/contracts/gen_phoenix.go
+++ b/core/state/contracts/gen_phoenix.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// PhoenixABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployPhoenix(auth *bind.TransactOpts, backend bind.ContractBackend) (libco
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PhoenixBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(PhoenixBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
diff --git a/core/state/contracts/gen_poly.go b/core/state/contracts/gen_poly.go
index d19fabe2014..a1e16977c3a 100644
--- a/core/state/contracts/gen_poly.go
+++ b/core/state/contracts/gen_poly.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// PolyABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployPoly(auth *bind.TransactOpts, backend bind.ContractBackend) (libcommo
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PolyBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(PolyBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
@@ -211,6 +213,43 @@ func (_Poly *PolyTransactorSession) Deploy(salt *big.Int) (types.Transaction, er
return _Poly.Contract.Deploy(&_Poly.TransactOpts, salt)
}
+// PolyDeployParams is an auto generated read-only Go binding of transcaction calldata params
+type PolyDeployParams struct {
+ Param_salt *big.Int
+}
+
+// Parse Deploy method from calldata of a transaction
+//
+// Solidity: function deploy(uint256 salt) returns()
+func ParsePolyDeployParams(calldata []byte) (*PolyDeployParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(PolyABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["deploy"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack deploy params data: %w", err)
+ }
+
+ var paramsResult = new(PolyDeployParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &PolyDeployParams{
+ Param_salt: out0,
+ }, nil
+}
+
// PolyDeployEventIterator is returned from FilterDeployEvent and is used to iterate over the raw logs and unpacked data for DeployEvent events raised by the Poly contract.
type PolyDeployEventIterator struct {
Event *PolyDeployEvent // Event containing the contract specifics and raw log
@@ -284,6 +323,10 @@ type PolyDeployEvent struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_Poly *PolyFilterer) DeployEventEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb")
+}
+
// FilterDeployEvent is a free log retrieval operation binding the contract event 0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb.
//
// Solidity: event DeployEvent(address d)
@@ -341,5 +384,6 @@ func (_Poly *PolyFilterer) ParseDeployEvent(log types.Log) (*PolyDeployEvent, er
if err := _Poly.contract.UnpackLog(event, "DeployEvent", log); err != nil {
return nil, err
}
+ event.Raw = log
return event, nil
}
diff --git a/core/state/contracts/gen_revive.go b/core/state/contracts/gen_revive.go
index af48b7bf9c6..3ff550781d0 100644
--- a/core/state/contracts/gen_revive.go
+++ b/core/state/contracts/gen_revive.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// ReviveABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployRevive(auth *bind.TransactOpts, backend bind.ContractBackend) (libcom
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ReviveBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(ReviveBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
@@ -211,6 +213,43 @@ func (_Revive *ReviveTransactorSession) Deploy(salt *big.Int) (types.Transaction
return _Revive.Contract.Deploy(&_Revive.TransactOpts, salt)
}
+// ReviveDeployParams is an auto generated read-only Go binding of transcaction calldata params
+type ReviveDeployParams struct {
+ Param_salt *big.Int
+}
+
+// Parse Deploy method from calldata of a transaction
+//
+// Solidity: function deploy(uint256 salt) returns()
+func ParseReviveDeployParams(calldata []byte) (*ReviveDeployParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(ReviveABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["deploy"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack deploy params data: %w", err)
+ }
+
+ var paramsResult = new(ReviveDeployParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &ReviveDeployParams{
+ Param_salt: out0,
+ }, nil
+}
+
// ReviveDeployEventIterator is returned from FilterDeployEvent and is used to iterate over the raw logs and unpacked data for DeployEvent events raised by the Revive contract.
type ReviveDeployEventIterator struct {
Event *ReviveDeployEvent // Event containing the contract specifics and raw log
@@ -284,6 +323,10 @@ type ReviveDeployEvent struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_Revive *ReviveFilterer) DeployEventEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb")
+}
+
// FilterDeployEvent is a free log retrieval operation binding the contract event 0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb.
//
// Solidity: event DeployEvent(address d)
@@ -341,5 +384,6 @@ func (_Revive *ReviveFilterer) ParseDeployEvent(log types.Log) (*ReviveDeployEve
if err := _Revive.contract.UnpackLog(event, "DeployEvent", log); err != nil {
return nil, err
}
+ event.Raw = log
return event, nil
}
diff --git a/core/state/contracts/gen_revive2.go b/core/state/contracts/gen_revive2.go
index 588bba45b9b..f3f880f2dd4 100644
--- a/core/state/contracts/gen_revive2.go
+++ b/core/state/contracts/gen_revive2.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// Revive2ABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployRevive2(auth *bind.TransactOpts, backend bind.ContractBackend) (libco
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Revive2Bin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(Revive2Bin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
@@ -211,6 +213,43 @@ func (_Revive2 *Revive2TransactorSession) Deploy(salt [32]byte) (types.Transacti
return _Revive2.Contract.Deploy(&_Revive2.TransactOpts, salt)
}
+// Revive2DeployParams is an auto generated read-only Go binding of transcaction calldata params
+type Revive2DeployParams struct {
+ Param_salt [32]byte
+}
+
+// Parse Deploy method from calldata of a transaction
+//
+// Solidity: function deploy(bytes32 salt) returns()
+func ParseRevive2DeployParams(calldata []byte) (*Revive2DeployParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(Revive2ABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["deploy"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack deploy params data: %w", err)
+ }
+
+ var paramsResult = new(Revive2DeployParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return &Revive2DeployParams{
+ Param_salt: out0,
+ }, nil
+}
+
// Revive2DeployEventIterator is returned from FilterDeployEvent and is used to iterate over the raw logs and unpacked data for DeployEvent events raised by the Revive2 contract.
type Revive2DeployEventIterator struct {
Event *Revive2DeployEvent // Event containing the contract specifics and raw log
@@ -284,6 +323,10 @@ type Revive2DeployEvent struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_Revive2 *Revive2Filterer) DeployEventEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb")
+}
+
// FilterDeployEvent is a free log retrieval operation binding the contract event 0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb.
//
// Solidity: event DeployEvent(address d)
@@ -341,5 +384,6 @@ func (_Revive2 *Revive2Filterer) ParseDeployEvent(log types.Log) (*Revive2Deploy
if err := _Revive2.contract.UnpackLog(event, "DeployEvent", log); err != nil {
return nil, err
}
+ event.Raw = log
return event, nil
}
diff --git a/core/state/contracts/gen_selfdestruct.go b/core/state/contracts/gen_selfdestruct.go
index cea4977b7d9..92178b14ef1 100644
--- a/core/state/contracts/gen_selfdestruct.go
+++ b/core/state/contracts/gen_selfdestruct.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// SelfdestructABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeploySelfdestruct(auth *bind.TransactOpts, backend bind.ContractBackend) (
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(SelfdestructBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(SelfdestructBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
diff --git a/core/state/database_test.go b/core/state/database_test.go
index 9f019f49fba..4ca21c21839 100644
--- a/core/state/database_test.go
+++ b/core/state/database_test.go
@@ -31,6 +31,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/erigontech/erigon-lib/chain"
+ "github.com/erigontech/erigon-lib/common"
libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/crypto"
"github.com/erigontech/erigon-lib/kv"
@@ -132,10 +133,14 @@ func TestCreate2Revive(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected contractAddress to not exist before block 0", contractAddress.String())
}
return nil
@@ -149,7 +154,9 @@ func TestCreate2Revive(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
return nil
@@ -165,7 +172,9 @@ func TestCreate2Revive(t *testing.T) {
var check2 uint256.Int
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(create2address) {
+ if exist, err := st.Exist(create2address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected create2address to exist at the block 2", create2address.String())
}
// We expect number 0x42 in the position [2], because it is the block number 2
@@ -184,7 +193,9 @@ func TestCreate2Revive(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if st.Exist(create2address) {
+ if exist, err := st.Exist(create2address); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected create2address to be self-destructed at the block 3", create2address.String())
}
return nil
@@ -197,7 +208,9 @@ func TestCreate2Revive(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(create2address) {
+ if exist, err := st.Exist(create2address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected create2address to exist at the block 2", create2address.String())
}
// We expect number 0x42 in the position [4], because it is the block number 4
@@ -338,10 +351,14 @@ func TestCreate2Polymorth(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected contractAddress to not exist before block 0", contractAddress.String())
}
return nil
@@ -354,9 +371,10 @@ func TestCreate2Polymorth(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
-
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
return nil
@@ -370,15 +388,25 @@ func TestCreate2Polymorth(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(create2address) {
+ if exist, err := st.Exist(create2address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected create2address to exist at the block 2", create2address.String())
}
- if !bytes.Equal(st.GetCode(create2address), libcommon.FromHex("6002ff")) {
- t.Errorf("Expected CREATE2 deployed code 6002ff, got %x", st.GetCode(create2address))
+ code, err := st.GetCode(create2address)
+ if err != nil {
+ return err
+ }
+ if !bytes.Equal(code, common.FromHex("6002ff")) {
+ t.Errorf("Expected CREATE2 deployed code 6002ff, got %x", code)
}
if !m.HistoryV3 { //AccountsDomain: has no "incarnation" concept
- if st.GetIncarnation(create2address) != 1 {
- t.Errorf("expected incarnation 1, got %d", st.GetIncarnation(create2address))
+ incarnation, err := st.GetIncarnation(create2address)
+ if err != nil {
+ return err
+ }
+ if incarnation != 1 {
+ t.Errorf("expected incarnation 1, got %d", incarnation)
}
}
return nil
@@ -391,7 +419,9 @@ func TestCreate2Polymorth(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if st.Exist(create2address) {
+ if exist, err := st.Exist(create2address); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected create2address to be self-destructed at the block 3", create2address.String())
}
return nil
@@ -404,15 +434,25 @@ func TestCreate2Polymorth(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(create2address) {
+ if exist, err := st.Exist(create2address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected create2address to exist at the block 4", create2address.String())
}
- if !bytes.Equal(st.GetCode(create2address), libcommon.FromHex("6004ff")) {
- t.Errorf("Expected CREATE2 deployed code 6004ff, got %x", st.GetCode(create2address))
+ code, err := st.GetCode(create2address)
+ if err != nil {
+ return err
+ }
+ if !bytes.Equal(code, common.FromHex("6004ff")) {
+ t.Errorf("Expected CREATE2 deployed code 6004ff, got %x", code)
}
if !m.HistoryV3 { //AccountsDomain: has no "incarnation" concept
- if st.GetIncarnation(create2address) != 2 {
- t.Errorf("expected incarnation 2, got %d", st.GetIncarnation(create2address))
+ incarnation, err := st.GetIncarnation(create2address)
+ if err != nil {
+ return err
+ }
+ if incarnation != 2 {
+ t.Errorf("expected incarnation 2, got %d", incarnation)
}
}
return nil
@@ -425,16 +465,26 @@ func TestCreate2Polymorth(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(create2address) {
+ if exist, err := st.Exist(create2address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected create2address to exist at the block 5", create2address.String())
}
- if !bytes.Equal(st.GetCode(create2address), libcommon.FromHex("6005ff")) {
- t.Errorf("Expected CREATE2 deployed code 6005ff, got %x", st.GetCode(create2address))
+ code, err := st.GetCode(create2address)
+ if err != nil {
+ return err
+ }
+ if !bytes.Equal(code, common.FromHex("6005ff")) {
+ t.Errorf("Expected CREATE2 deployed code 6005ff, got %x", code)
}
if !m.HistoryV3 { //AccountsDomain: has no "incarnation" concept
- if st.GetIncarnation(create2address) != 4 {
- t.Errorf("expected incarnation 4 (two self-destructs and two-recreations within a block), got %d", st.GetIncarnation(create2address))
+ incarnation, err := st.GetIncarnation(create2address)
+ if err != nil {
+ return err
+ }
+ if incarnation != 4 {
+ t.Errorf("expected incarnation 4 (two self-destructs and two-recreations within a block), got %d", incarnation)
}
}
return nil
@@ -531,10 +581,14 @@ func TestReorgOverSelfDestruct(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected contractAddress to not exist before block 0", contractAddress.String())
}
return nil
@@ -549,7 +603,10 @@ func TestReorgOverSelfDestruct(t *testing.T) {
var correctValueX uint256.Int
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
+
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
@@ -566,7 +623,9 @@ func TestReorgOverSelfDestruct(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected contractAddress to not exist at the block 3", contractAddress.String())
}
return nil
@@ -578,7 +637,9 @@ func TestReorgOverSelfDestruct(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 4", contractAddress.String())
}
var valueX uint256.Int
@@ -671,10 +732,15 @@ func TestReorgOverStateChange(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if exist {
+
t.Error("expected contractAddress to not exist before block 0", contractAddress.String())
}
return nil
@@ -690,7 +756,10 @@ func TestReorgOverStateChange(t *testing.T) {
var correctValueX uint256.Int
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
+
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
@@ -711,7 +780,9 @@ func TestReorgOverStateChange(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 4", contractAddress.String())
}
@@ -801,7 +872,9 @@ func TestCreateOnExistingStorage(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
if contractAddress != contractAddr {
@@ -820,7 +893,9 @@ func TestCreateOnExistingStorage(t *testing.T) {
var check0 uint256.Int
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
@@ -947,14 +1022,18 @@ func TestEip2200Gas(t *testing.T) {
var balanceBefore *uint256.Int
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected contractAddress to not exist before block 0", contractAddress.String())
}
- balanceBefore = st.GetBalance(address)
- return nil
+ balanceBefore, err = st.GetBalance(address)
+ return err
})
require.NoError(t, err)
@@ -965,10 +1044,15 @@ func TestEip2200Gas(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
- balanceAfter := st.GetBalance(address)
+ balanceAfter, err := st.GetBalance(address)
+ if err != nil {
+ return err
+ }
gasSpent := big.NewInt(0).Sub(balanceBefore.ToBig(), balanceAfter.ToBig())
expectedGasSpent := big.NewInt(190373) //(192245) // In the incorrect version, it is 179645
if gasSpent.Cmp(expectedGasSpent) != 0 {
@@ -1035,10 +1119,14 @@ func TestWrongIncarnation(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if exist {
t.Error("expected contractAddress to not exist before block 0", contractAddress.String())
}
return nil
@@ -1065,7 +1153,9 @@ func TestWrongIncarnation(t *testing.T) {
}
st := state.New(stateReader)
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
return nil
@@ -1185,7 +1275,9 @@ func TestWrongIncarnation2(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ if exist, err := st.Exist(address); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected account to exist")
}
return nil
@@ -1204,7 +1296,9 @@ func TestWrongIncarnation2(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(contractAddress) {
+ if exist, err := st.Exist(contractAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Error("expected contractAddress to exist at the block 1", contractAddress.String())
}
@@ -1529,7 +1623,9 @@ func TestRecreateAndRewind(t *testing.T) {
var check0 uint256.Int
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(phoenixAddress) {
+ if exist, err := st.Exist(phoenixAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Errorf("expected phoenix %x to exist after first insert", phoenixAddress)
}
@@ -1548,7 +1644,9 @@ func TestRecreateAndRewind(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(phoenixAddress) {
+ if exist, err := st.Exist(phoenixAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Errorf("expected phoenix %x to exist after second insert", phoenixAddress)
}
@@ -1566,7 +1664,9 @@ func TestRecreateAndRewind(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(phoenixAddress) {
+ if exist, err := st.Exist(phoenixAddress); err != nil {
+ t.Error(err)
+ } else if !exist {
t.Errorf("expected phoenix %x to exist after second insert", phoenixAddress)
}
diff --git a/core/state/intra_block_state.go b/core/state/intra_block_state.go
index 030a630bdea..dbd3ee0fbfd 100644
--- a/core/state/intra_block_state.go
+++ b/core/state/intra_block_state.go
@@ -126,12 +126,14 @@ func (sdb *IntraBlockState) SetTrace(trace bool) {
}
// setErrorUnsafe sets error but should be called in medhods that already have locks
+// Deprecated: The IBS api now returns errors directly
func (sdb *IntraBlockState) setErrorUnsafe(err error) {
if sdb.savedErr == nil {
sdb.savedErr = err
}
}
+// Deprecated: The IBS api now returns errors directly
func (sdb *IntraBlockState) Error() error {
return sdb.savedErr
}
@@ -230,36 +232,47 @@ func (sdb *IntraBlockState) SubRefund(gas uint64) {
// Exist reports whether the given account address exists in the state.
// Notably this also returns true for suicided accounts.
-func (sdb *IntraBlockState) Exist(addr libcommon.Address) bool {
- s := sdb.getStateObject(addr)
- return s != nil && !s.deleted
+func (sdb *IntraBlockState) Exist(addr libcommon.Address) (bool, error) {
+ s, err := sdb.getStateObject(addr)
+ if err != nil {
+ return false, err
+ }
+ return s != nil && !s.deleted, err
}
// Empty returns whether the state object is either non-existent
// or empty according to the EIP161 specification (balance = nonce = code = 0)
-func (sdb *IntraBlockState) Empty(addr libcommon.Address) bool {
- so := sdb.getStateObject(addr)
- return so == nil || so.deleted || so.empty()
+func (sdb *IntraBlockState) Empty(addr libcommon.Address) (bool, error) {
+ so, err := sdb.getStateObject(addr)
+ if err != nil {
+ return false, err
+ }
+ return so == nil || so.deleted || so.empty(), nil
}
// GetBalance retrieves the balance from the given address or 0 if object not found
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) GetBalance(addr libcommon.Address) *uint256.Int {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetBalance(addr libcommon.Address) (*uint256.Int, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return nil, err
+ }
if stateObject != nil && !stateObject.deleted {
- return stateObject.Balance()
+ return stateObject.Balance(), nil
}
- return u256.Num0
+ return u256.Num0, nil
}
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) GetNonce(addr libcommon.Address) uint64 {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetNonce(addr libcommon.Address) (uint64, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return 0, err
+ }
if stateObject != nil && !stateObject.deleted {
- return stateObject.Nonce()
+ return stateObject.Nonce(), nil
}
-
- return 0
+ return 0, nil
}
// TxIndex returns the current transaction index set by Prepare.
@@ -268,120 +281,160 @@ func (sdb *IntraBlockState) TxnIndex() int {
}
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) GetCode(addr libcommon.Address) []byte {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetCode(addr libcommon.Address) ([]byte, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return nil, err
+ }
if stateObject != nil && !stateObject.deleted {
if sdb.trace {
fmt.Printf("GetCode %x, returned %d\n", addr, len(stateObject.Code()))
}
- return stateObject.Code()
+ return stateObject.Code(), nil
}
if sdb.trace {
fmt.Printf("GetCode %x, returned nil\n", addr)
}
- return nil
+ return nil, nil
}
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) GetCodeSize(addr libcommon.Address) int {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetCodeSize(addr libcommon.Address) (int, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return 0, err
+ }
if stateObject == nil || stateObject.deleted {
- return 0
+ return 0, nil
}
if stateObject.code != nil {
- return len(stateObject.code)
+ return len(stateObject.code), nil
}
if stateObject.data.CodeHash == emptyCodeHashH {
- return 0
+ return 0, nil
}
l, err := sdb.stateReader.ReadAccountCodeSize(addr, stateObject.data.Incarnation)
if err != nil {
sdb.setErrorUnsafe(err)
+ return l, err
}
- return l
+ return l, err
}
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) GetCodeHash(addr libcommon.Address) libcommon.Hash {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetCodeHash(addr libcommon.Address) (libcommon.Hash, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return libcommon.Hash{}, err
+ }
if stateObject == nil || stateObject.deleted {
- return libcommon.Hash{}
+ return libcommon.Hash{}, nil
}
- return stateObject.data.CodeHash
+ return stateObject.data.CodeHash, nil
}
-func (sdb *IntraBlockState) ResolveCodeHash(addr libcommon.Address) libcommon.Hash {
+func (sdb *IntraBlockState) ResolveCodeHash(addr libcommon.Address) (libcommon.Hash, error) {
// eip-7702
- if dd, ok := sdb.GetDelegatedDesignation(addr); ok {
+ dd, ok, err := sdb.GetDelegatedDesignation(addr)
+
+ if ok {
return sdb.GetCodeHash(dd)
}
+ if err != nil {
+ return libcommon.Hash{}, err
+ }
+
return sdb.GetCodeHash(addr)
}
-func (sdb *IntraBlockState) ResolveCode(addr libcommon.Address) []byte {
+func (sdb *IntraBlockState) ResolveCode(addr libcommon.Address) ([]byte, error) {
// eip-7702
- if dd, ok := sdb.GetDelegatedDesignation(addr); ok {
+ dd, ok, err := sdb.GetDelegatedDesignation(addr)
+ if ok {
return sdb.GetCode(dd)
}
-
+ if err != nil {
+ return nil, err
+ }
return sdb.GetCode(addr)
}
-func (sdb *IntraBlockState) ResolveCodeSize(addr libcommon.Address) int {
+func (sdb *IntraBlockState) ResolveCodeSize(addr libcommon.Address) (int, error) {
// eip-7702
- size := sdb.GetCodeSize(addr)
+ size, err := sdb.GetCodeSize(addr)
+ if err != nil {
+ return 0, err
+ }
if size == types.DelegateDesignationCodeSize {
// might be delegated designation
- return len(sdb.ResolveCode(addr))
+ code, err := sdb.ResolveCode(addr)
+ if err != nil {
+ return 0, err
+ }
+ return len(code), nil
}
- return size
+ return size, nil
}
-func (sdb *IntraBlockState) GetDelegatedDesignation(addr libcommon.Address) (libcommon.Address, bool) {
+func (sdb *IntraBlockState) GetDelegatedDesignation(addr libcommon.Address) (libcommon.Address, bool, error) {
// eip-7702
- code := sdb.GetCode(addr)
+ code, err := sdb.GetCode(addr)
+ if err != nil {
+ return EmptyAddress, false, err
+ }
if delegation, ok := types.ParseDelegation(code); ok {
- return delegation, true
+ return delegation, true, nil
}
- return EmptyAddress, false
+ return EmptyAddress, false, nil
}
// GetState retrieves a value from the given account's storage trie.
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) GetState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) error {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil && !stateObject.deleted {
stateObject.GetState(key, value)
} else {
value.Clear()
}
+ return nil
}
// GetCommittedState retrieves a value from the given account's committed storage trie.
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) GetCommittedState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetCommittedState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) error {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil && !stateObject.deleted {
stateObject.GetCommittedState(key, value)
} else {
value.Clear()
}
+ return nil
}
-func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) bool {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) (bool, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return false, err
+ }
if stateObject == nil {
- return false
+ return false, nil
}
if stateObject.deleted {
- return false
+ return false, nil
}
if stateObject.createdContract {
- return false
+ return false, nil
}
- return stateObject.selfdestructed
+ return stateObject.selfdestructed, nil
}
/*
@@ -390,7 +443,7 @@ func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) bool {
// AddBalance adds amount to the account associated with addr.
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) {
+func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) error {
if sdb.trace {
fmt.Printf("AddBalance %x, %d\n", addr, amount)
}
@@ -427,82 +480,117 @@ func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.I
bi.increase.Add(&bi.increase, amount)
bi.count++
- return
+ return nil
}
- stateObject := sdb.GetOrNewStateObject(addr)
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
stateObject.AddBalance(amount, reason)
+ return nil
}
// SubBalance subtracts amount from the account associated with addr.
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) SubBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) {
+func (sdb *IntraBlockState) SubBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) error {
if sdb.trace {
fmt.Printf("SubBalance %x, %d\n", addr, amount)
}
- stateObject := sdb.GetOrNewStateObject(addr)
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil {
stateObject.SubBalance(amount, reason)
}
+ return nil
}
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) SetBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) {
- stateObject := sdb.GetOrNewStateObject(addr)
+func (sdb *IntraBlockState) SetBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) error {
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil {
stateObject.SetBalance(amount, reason)
}
+ return nil
}
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) SetNonce(addr libcommon.Address, nonce uint64) {
- stateObject := sdb.GetOrNewStateObject(addr)
+func (sdb *IntraBlockState) SetNonce(addr libcommon.Address, nonce uint64) error {
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil {
stateObject.SetNonce(nonce)
}
+ return nil
}
// DESCRIBED: docs/programmers_guide/guide.md#code-hash
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) SetCode(addr libcommon.Address, code []byte) {
- stateObject := sdb.GetOrNewStateObject(addr)
+func (sdb *IntraBlockState) SetCode(addr libcommon.Address, code []byte) error {
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil {
stateObject.SetCode(crypto.Keccak256Hash(code), code)
}
+ return nil
}
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
-func (sdb *IntraBlockState) SetState(addr libcommon.Address, key *libcommon.Hash, value uint256.Int) {
- stateObject := sdb.GetOrNewStateObject(addr)
+func (sdb *IntraBlockState) SetState(addr libcommon.Address, key *libcommon.Hash, value uint256.Int) error {
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil {
stateObject.SetState(key, value)
}
+ return nil
}
// SetStorage replaces the entire storage for the specified account with given
// storage. This function should only be used for debugging.
-func (sdb *IntraBlockState) SetStorage(addr libcommon.Address, storage Storage) {
- stateObject := sdb.GetOrNewStateObject(addr)
+func (sdb *IntraBlockState) SetStorage(addr libcommon.Address, storage Storage) error {
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil {
stateObject.SetStorage(storage)
}
+ return nil
}
// SetIncarnation sets incarnation for account if account exists
-func (sdb *IntraBlockState) SetIncarnation(addr libcommon.Address, incarnation uint64) {
- stateObject := sdb.GetOrNewStateObject(addr)
+func (sdb *IntraBlockState) SetIncarnation(addr libcommon.Address, incarnation uint64) error {
+ stateObject, err := sdb.GetOrNewStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject != nil {
stateObject.setIncarnation(incarnation)
}
+ return nil
}
-func (sdb *IntraBlockState) GetIncarnation(addr libcommon.Address) uint64 {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetIncarnation(addr libcommon.Address) (uint64, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return 0, err
+ }
if stateObject != nil {
- return stateObject.data.Incarnation
+ return stateObject.data.Incarnation, nil
}
- return 0
+ return 0, nil
}
// Selfdestruct marks the given account as suicided.
@@ -510,10 +598,13 @@ func (sdb *IntraBlockState) GetIncarnation(addr libcommon.Address) uint64 {
//
// The account's state object is still available until the state is committed,
// getStateObject will return a non-nil account after Suicide.
-func (sdb *IntraBlockState) Selfdestruct(addr libcommon.Address) bool {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) Selfdestruct(addr libcommon.Address) (bool, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return false, err
+ }
if stateObject == nil || stateObject.deleted {
- return false
+ return false, nil
}
prevBalance := *stateObject.Balance()
@@ -531,19 +622,27 @@ func (sdb *IntraBlockState) Selfdestruct(addr libcommon.Address) bool {
stateObject.createdContract = false
stateObject.data.Balance.Clear()
- return true
+ return true, nil
}
-func (sdb *IntraBlockState) Selfdestruct6780(addr libcommon.Address) {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) Selfdestruct6780(addr libcommon.Address) error {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return err
+ }
if stateObject == nil {
- return
+ return nil
}
if stateObject.newlyCreated {
- if _, ok := types.ParseDelegation(sdb.GetCode(addr)); !ok {
+ code, err := sdb.GetCode(addr)
+ if err != nil {
+ return err
+ }
+ if _, ok := types.ParseDelegation(code); !ok {
sdb.Selfdestruct(addr)
}
}
+ return nil
}
// SetTransientState sets transient storage for a given account. It
@@ -575,36 +674,36 @@ func (sdb *IntraBlockState) GetTransientState(addr libcommon.Address, key libcom
return sdb.transientStorage.Get(addr, key)
}
-func (sdb *IntraBlockState) getStateObject(addr libcommon.Address) (stateObject *stateObject) {
+func (sdb *IntraBlockState) getStateObject(addr libcommon.Address) (stateObject *stateObject, err error) {
// Prefer 'live' objects.
if obj := sdb.stateObjects[addr]; obj != nil {
- return obj
+ return obj, nil
}
// Load the object from the database.
if _, ok := sdb.nilAccounts[addr]; ok {
if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred {
- return sdb.createObject(addr, nil)
+ return sdb.createObject(addr, nil), nil
}
- return nil
+ return nil, nil
}
account, err := sdb.stateReader.ReadAccountData(addr)
if err != nil {
sdb.setErrorUnsafe(err)
- return nil
+ return nil, err
}
if account == nil {
sdb.nilAccounts[addr] = struct{}{}
if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred {
- return sdb.createObject(addr, nil)
+ return sdb.createObject(addr, nil), nil
}
- return nil
+ return nil, nil
}
// Insert into the live set.
obj := newObject(sdb, addr, account, account)
sdb.setStateObject(addr, obj)
- return obj
+ return obj, nil
}
func (sdb *IntraBlockState) setStateObject(addr libcommon.Address, object *stateObject) {
@@ -617,12 +716,15 @@ func (sdb *IntraBlockState) setStateObject(addr libcommon.Address, object *state
}
// Retrieve a state object or create a new state object if nil.
-func (sdb *IntraBlockState) GetOrNewStateObject(addr libcommon.Address) *stateObject {
- stateObject := sdb.getStateObject(addr)
+func (sdb *IntraBlockState) GetOrNewStateObject(addr libcommon.Address) (*stateObject, error) {
+ stateObject, err := sdb.getStateObject(addr)
+ if err != nil {
+ return nil, err
+ }
if stateObject == nil || stateObject.deleted {
stateObject = sdb.createObject(addr, stateObject /* previous */)
}
- return stateObject
+ return stateObject, nil
}
// createObject creates a new state object. If there is an existing account with
@@ -658,9 +760,12 @@ func (sdb *IntraBlockState) createObject(addr libcommon.Address, previous *state
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
//
// Carrying over the balance ensures that Ether doesn't disappear.
-func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreation bool) {
+func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreation bool) error {
var prevInc uint64
- previous := sdb.getStateObject(addr)
+ previous, err := sdb.getStateObject(addr)
+ if err != nil {
+ return err
+ }
if previous != nil && previous.selfdestructed {
prevInc = previous.data.Incarnation
} else {
@@ -668,6 +773,7 @@ func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreati
prevInc = inc
} else {
sdb.savedErr = err
+ return err
}
}
if previous != nil && prevInc < previous.data.PrevIncarnation {
@@ -687,6 +793,7 @@ func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreati
} else {
newObj.selfdestructed = false
}
+ return nil
}
// Snapshot returns an identifier for the current revision of the state.
@@ -910,7 +1017,7 @@ func (sdb *IntraBlockState) clearJournalAndRefund() {
// - Add authorities to access list (EIP-7702)
// - Add delegated designation (if it exists for dst) to access list (EIP-7702)
func (sdb *IntraBlockState) Prepare(rules *chain.Rules, sender, coinbase libcommon.Address, dst *libcommon.Address,
- precompiles []libcommon.Address, list types.AccessList, authorities []libcommon.Address) {
+ precompiles []libcommon.Address, list types.AccessList, authorities []libcommon.Address) error {
if sdb.trace {
fmt.Printf("ibs.Prepare %x, %x, %x, %x, %v, %v, %v\n", sender, coinbase, dst, precompiles, list, rules, authorities)
}
@@ -945,13 +1052,18 @@ func (sdb *IntraBlockState) Prepare(rules *chain.Rules, sender, coinbase libcomm
}
if dst != nil {
- if dd, ok := sdb.GetDelegatedDesignation(*dst); ok {
+ dd, ok, err := sdb.GetDelegatedDesignation(*dst)
+ if err != nil {
+ return err
+ }
+ if ok {
sdb.AddAddressToAccessList(dd)
}
}
}
// Reset transient storage at the beginning of transaction execution
sdb.transientStorage = newTransientStorage()
+ return nil
}
// AddAddressToAccessList adds the given address to the access list
diff --git a/core/state/intra_block_state_logger_test.go b/core/state/intra_block_state_logger_test.go
index 11c5023c940..cc5fed21804 100644
--- a/core/state/intra_block_state_logger_test.go
+++ b/core/state/intra_block_state_logger_test.go
@@ -86,7 +86,8 @@ func TestStateLogger(t *testing.T) {
}
}
- so := stateDB.GetOrNewStateObject(libcommon.Address{})
+ so, err := stateDB.GetOrNewStateObject(libcommon.Address{})
+ require.NoError(t, err)
if !reflect.DeepEqual(so.Balance(), uint256.NewInt(3)) {
t.Errorf("Incorrect Balance for %s expectedBalance: %s, got:%s", libcommon.Address{}, uint256.NewInt(3), so.Balance())
}
@@ -103,7 +104,8 @@ func TestStateLogger(t *testing.T) {
state.SubBalance(libcommon.Address{}, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
},
checker: func(t *testing.T, stateDB *IntraBlockState) {
- so := stateDB.GetOrNewStateObject(libcommon.Address{})
+ so, err := stateDB.GetOrNewStateObject(libcommon.Address{})
+ require.NoError(t, err)
if !reflect.DeepEqual(so.Balance(), uint256.NewInt(1)) {
t.Errorf("Incorrect Balance for %s expectedBalance: %s, got:%s", libcommon.Address{}, uint256.NewInt(1), so.Balance())
}
diff --git a/core/state/intra_block_state_test.go b/core/state/intra_block_state_test.go
index b2c1c5321e6..f7d0767015c 100644
--- a/core/state/intra_block_state_test.go
+++ b/core/state/intra_block_state_test.go
@@ -323,17 +323,77 @@ func (test *snapshotTest) checkEqual(state, checkstate *IntraBlockState) error {
return true
}
// Check basic accessor methods.
- if !checkeq("Exist", state.Exist(addr), checkstate.Exist(addr)) {
+ se, err := state.Exist(addr)
+ if err != nil {
return err
}
- checkeq("HasSelfdestructed", state.HasSelfdestructed(addr), checkstate.HasSelfdestructed(addr))
- checkeqBigInt("GetBalance", state.GetBalance(addr).ToBig(), checkstate.GetBalance(addr).ToBig())
- checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr))
- checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr))
- checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr))
- checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr))
+ ce, err := checkstate.Exist(addr)
+ if err != nil {
+ return err
+ }
+ if !checkeq("Exist", se, ce) {
+ return err
+ }
+ ssd, err := state.HasSelfdestructed(addr)
+ if err != nil {
+ return err
+ }
+ csd, err := checkstate.HasSelfdestructed(addr)
+ if err != nil {
+ return err
+ }
+ checkeq("HasSelfdestructed", ssd, csd)
+ sb, err := state.GetBalance(addr)
+ if err != nil {
+ return err
+ }
+ cb, err := checkstate.GetBalance(addr)
+ if err != nil {
+ return err
+ }
+ checkeqBigInt("GetBalance", sb.ToBig(), cb.ToBig())
+ sn, err := state.GetNonce(addr)
+ if err != nil {
+ return err
+ }
+ cn, err := checkstate.GetNonce(addr)
+ if err != nil {
+ return err
+ }
+ checkeq("GetNonce", sn, cn)
+ sc, err := state.GetCode(addr)
+ if err != nil {
+ return err
+ }
+ cc, err := checkstate.GetCode(addr)
+ if err != nil {
+ return err
+ }
+ checkeq("GetCode", sc, cc)
+ sch, err := state.GetCodeHash(addr)
+ if err != nil {
+ return err
+ }
+ cch, err := checkstate.GetCodeHash(addr)
+ if err != nil {
+ return err
+ }
+ checkeq("GetCodeHash", sch, cch)
+ scs, err := state.GetCodeSize(addr)
+ if err != nil {
+ return err
+ }
+ ccs, err := checkstate.GetCodeSize(addr)
+ if err != nil {
+ return err
+ }
+ checkeq("GetCodeSize", scs, ccs)
// Check storage.
- if obj := state.getStateObject(addr); obj != nil {
+ obj, err := state.getStateObject(addr)
+ if err != nil {
+ return err
+ }
+ if obj != nil {
for key, value := range obj.dirtyStorage {
var out uint256.Int
checkstate.GetState(addr, &key, &out)
@@ -342,7 +402,11 @@ func (test *snapshotTest) checkEqual(state, checkstate *IntraBlockState) error {
}
}
}
- if obj := checkstate.getStateObject(addr); obj != nil {
+ obj, err = checkstate.getStateObject(addr)
+ if err != nil {
+ return err
+ }
+ if obj != nil {
for key, value := range obj.dirtyStorage {
var out uint256.Int
state.GetState(addr, &key, &out)
diff --git a/core/state/journal.go b/core/state/journal.go
index 663f70baeb9..fd7dc7fa13a 100644
--- a/core/state/journal.go
+++ b/core/state/journal.go
@@ -29,7 +29,7 @@ import (
// reverted on demand.
type journalEntry interface {
// revert undoes the changes introduced by this journal entry.
- revert(*IntraBlockState)
+ revert(*IntraBlockState) error
// dirtied returns the Ethereum address modified by this journal entry.
dirtied() *libcommon.Address
@@ -172,29 +172,35 @@ type (
// refundChange | addLogChange | touchChange | accessListAddAccountChange | accessListAddSlotChange | transientStorageChange
//}
-func (ch createObjectChange) revert(s *IntraBlockState) {
+func (ch createObjectChange) revert(s *IntraBlockState) error {
delete(s.stateObjects, *ch.account)
delete(s.stateObjectsDirty, *ch.account)
+ return nil
}
func (ch createObjectChange) dirtied() *libcommon.Address {
return ch.account
}
-func (ch resetObjectChange) revert(s *IntraBlockState) {
+func (ch resetObjectChange) revert(s *IntraBlockState) error {
s.setStateObject(*ch.account, ch.prev)
+ return nil
}
func (ch resetObjectChange) dirtied() *libcommon.Address {
return nil
}
-func (ch selfdestructChange) revert(s *IntraBlockState) {
- obj := s.getStateObject(*ch.account)
+func (ch selfdestructChange) revert(s *IntraBlockState) error {
+ obj, err := s.getStateObject(*ch.account)
+ if err != nil {
+ return err
+ }
if obj != nil {
obj.selfdestructed = ch.prev
obj.setBalance(&ch.prevbalance)
}
+ return nil
}
func (ch selfdestructChange) dirtied() *libcommon.Address {
@@ -203,22 +209,28 @@ func (ch selfdestructChange) dirtied() *libcommon.Address {
var ripemd = libcommon.HexToAddress("0000000000000000000000000000000000000003")
-func (ch touchChange) revert(s *IntraBlockState) {
+func (ch touchChange) revert(s *IntraBlockState) error {
+ return nil
}
func (ch touchChange) dirtied() *libcommon.Address {
return ch.account
}
-func (ch balanceChange) revert(s *IntraBlockState) {
- s.getStateObject(*ch.account).setBalance(&ch.prev)
+func (ch balanceChange) revert(s *IntraBlockState) error {
+ obj, err := s.getStateObject(*ch.account)
+ if err != nil {
+ return err
+ }
+ obj.setBalance(&ch.prev)
+ return nil
}
func (ch balanceChange) dirtied() *libcommon.Address {
return ch.account
}
-func (ch balanceIncrease) revert(s *IntraBlockState) {
+func (ch balanceIncrease) revert(s *IntraBlockState) error {
if bi, ok := s.balanceInc[*ch.account]; ok {
bi.increase.Sub(&bi.increase, &ch.increase)
bi.count--
@@ -226,6 +238,7 @@ func (ch balanceIncrease) revert(s *IntraBlockState) {
delete(s.balanceInc, *ch.account)
}
}
+ return nil
}
func (ch balanceIncrease) dirtied() *libcommon.Address {
@@ -236,71 +249,95 @@ func (ch balanceIncreaseTransfer) dirtied() *libcommon.Address {
return nil
}
-func (ch balanceIncreaseTransfer) revert(s *IntraBlockState) {
+func (ch balanceIncreaseTransfer) revert(s *IntraBlockState) error {
ch.bi.transferred = false
+ return nil
}
-func (ch nonceChange) revert(s *IntraBlockState) {
- s.getStateObject(*ch.account).setNonce(ch.prev)
+func (ch nonceChange) revert(s *IntraBlockState) error {
+ obj, err := s.getStateObject(*ch.account)
+ if err != nil {
+ return err
+ }
+ obj.setNonce(ch.prev)
+ return nil
}
func (ch nonceChange) dirtied() *libcommon.Address {
return ch.account
}
-func (ch codeChange) revert(s *IntraBlockState) {
- s.getStateObject(*ch.account).setCode(ch.prevhash, ch.prevcode)
+func (ch codeChange) revert(s *IntraBlockState) error {
+ obj, err := s.getStateObject(*ch.account)
+ if err != nil {
+ return err
+ }
+ obj.setCode(ch.prevhash, ch.prevcode)
+ return nil
}
func (ch codeChange) dirtied() *libcommon.Address {
return ch.account
}
-func (ch storageChange) revert(s *IntraBlockState) {
- s.getStateObject(*ch.account).setState(&ch.key, ch.prevalue)
+func (ch storageChange) revert(s *IntraBlockState) error {
+ obj, err := s.getStateObject(*ch.account)
+ if err != nil {
+ return err
+ }
+ obj.setState(&ch.key, ch.prevalue)
+ return nil
}
func (ch storageChange) dirtied() *libcommon.Address {
return ch.account
}
-func (ch fakeStorageChange) revert(s *IntraBlockState) {
- s.getStateObject(*ch.account).fakeStorage[ch.key] = ch.prevalue
+func (ch fakeStorageChange) revert(s *IntraBlockState) error {
+ obj, err := s.getStateObject(*ch.account)
+ if err != nil {
+ return err
+ }
+ obj.fakeStorage[ch.key] = ch.prevalue
+ return nil
}
func (ch fakeStorageChange) dirtied() *libcommon.Address {
return ch.account
}
-func (ch transientStorageChange) revert(s *IntraBlockState) {
+func (ch transientStorageChange) revert(s *IntraBlockState) error {
s.setTransientState(*ch.account, ch.key, ch.prevalue)
+ return nil
}
func (ch transientStorageChange) dirtied() *libcommon.Address {
return nil
}
-func (ch refundChange) revert(s *IntraBlockState) {
+func (ch refundChange) revert(s *IntraBlockState) error {
s.refund = ch.prev
+ return nil
}
func (ch refundChange) dirtied() *libcommon.Address {
return nil
}
-func (ch addLogChange) revert(s *IntraBlockState) {
+func (ch addLogChange) revert(s *IntraBlockState) error {
txnLogs := s.logs[ch.txIndex]
s.logs[ch.txIndex] = txnLogs[:len(txnLogs)-1] // revert 1 log
if len(s.logs[ch.txIndex]) == 0 {
s.logs = s.logs[:len(s.logs)-1] // revert txn
}
s.logSize--
+ return nil
}
func (ch addLogChange) dirtied() *libcommon.Address {
return nil
}
-func (ch accessListAddAccountChange) revert(s *IntraBlockState) {
+func (ch accessListAddAccountChange) revert(s *IntraBlockState) error {
/*
One important invariant here, is that whenever a (addr, slot) is added, if the
addr is not already present, the add causes two journal entries:
@@ -311,14 +348,16 @@ func (ch accessListAddAccountChange) revert(s *IntraBlockState) {
a single (addr) change.
*/
s.accessList.DeleteAddress(*ch.address)
+ return nil
}
func (ch accessListAddAccountChange) dirtied() *libcommon.Address {
return nil
}
-func (ch accessListAddSlotChange) revert(s *IntraBlockState) {
+func (ch accessListAddSlotChange) revert(s *IntraBlockState) error {
s.accessList.DeleteSlot(*ch.address, *ch.slot)
+ return nil
}
func (ch accessListAddSlotChange) dirtied() *libcommon.Address {
diff --git a/core/state/state_test.go b/core/state/state_test.go
index 5dc2aab8e9e..7e3ad911053 100644
--- a/core/state/state_test.go
+++ b/core/state/state_test.go
@@ -57,15 +57,18 @@ var _ = checker.Suite(&StateSuite{})
func (s *StateSuite) TestDump(c *checker.C) {
// generate a few entries
- obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01}))
+ obj1, err := s.state.GetOrNewStateObject(toAddr([]byte{0x01}))
+ c.Check(err, checker.IsNil)
obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified)
- obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02}))
+ obj2, err := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02}))
+ c.Check(err, checker.IsNil)
obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3})
- obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02}))
+ obj3, err := s.state.GetOrNewStateObject(toAddr([]byte{0x02}))
+ c.Check(err, checker.IsNil)
obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified)
// write some of them to the trie
- err := s.w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account))
+ err = s.w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account))
c.Check(err, checker.IsNil)
err = s.w.UpdateAccountData(obj2.address, &obj2.data, new(accounts.Account))
c.Check(err, checker.IsNil)
@@ -273,7 +276,10 @@ func TestSnapshot2(t *testing.T) {
state.SetState(stateobjaddr1, &storageaddr, *data1)
// db, trie are already non-empty values
- so0 := state.getStateObject(stateobjaddr0)
+ so0, err := state.getStateObject(stateobjaddr0)
+ if err != nil {
+ t.Fatal("getting state", err)
+ }
so0.SetBalance(uint256.NewInt(42), tracing.BalanceChangeUnspecified)
so0.SetNonce(43)
so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'})
@@ -292,7 +298,10 @@ func TestSnapshot2(t *testing.T) {
}
// and one with deleted == true
- so1 := state.getStateObject(stateobjaddr1)
+ so1, err := state.getStateObject(stateobjaddr1)
+ if err != nil {
+ t.Fatal("getting state", err)
+ }
so1.SetBalance(uint256.NewInt(52), tracing.BalanceChangeUnspecified)
so1.SetNonce(53)
so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'})
@@ -300,7 +309,10 @@ func TestSnapshot2(t *testing.T) {
so1.deleted = true
state.setStateObject(stateobjaddr1, so1)
- so1 = state.getStateObject(stateobjaddr1)
+ so1, err = state.getStateObject(stateobjaddr1)
+ if err != nil {
+ t.Fatal("getting state", err)
+ }
if so1 != nil && !so1.deleted {
t.Fatalf("deleted object not nil when getting")
}
@@ -308,7 +320,10 @@ func TestSnapshot2(t *testing.T) {
snapshot := state.Snapshot()
state.RevertToSnapshot(snapshot)
- so0Restored := state.getStateObject(stateobjaddr0)
+ so0Restored, err := state.getStateObject(stateobjaddr0)
+ if err != nil {
+ t.Fatal("getting restored state", err)
+ }
// Update lazily-loaded values before comparing.
var tmp uint256.Int
so0Restored.GetState(&storageaddr, &tmp)
@@ -317,7 +332,10 @@ func TestSnapshot2(t *testing.T) {
compareStateObjects(so0Restored, so0, t)
// deleted should be nil, both before and after restore of state copy
- so1Restored := state.getStateObject(stateobjaddr1)
+ so1Restored, err := state.getStateObject(stateobjaddr1)
+ if err != nil {
+ t.Fatal("getting restored state", err)
+ }
if so1Restored != nil && !so1Restored.deleted {
t.Fatalf("deleted object not nil after restoring snapshot: %+v", so1Restored)
}
@@ -410,12 +428,15 @@ func TestDump(t *testing.T) {
st := New(NewReaderV3(domains))
// generate a few entries
- obj1 := st.GetOrNewStateObject(toAddr([]byte{0x01}))
+ obj1, err := st.GetOrNewStateObject(toAddr([]byte{0x01}))
+ require.NoError(t, err)
obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified)
- obj2 := st.GetOrNewStateObject(toAddr([]byte{0x01, 0x02}))
+ obj2, err := st.GetOrNewStateObject(toAddr([]byte{0x01, 0x02}))
+ require.NoError(t, err)
obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3})
obj2.setIncarnation(1)
- obj3 := st.GetOrNewStateObject(toAddr([]byte{0x02}))
+ obj3, err := st.GetOrNewStateObject(toAddr([]byte{0x02}))
+ require.NoError(t, err)
obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified)
w := NewWriterV4(domains)
diff --git a/core/state/stateless.go b/core/state/stateless.go
new file mode 100644
index 00000000000..81c43cf423a
--- /dev/null
+++ b/core/state/stateless.go
@@ -0,0 +1,366 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package state
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/holiman/uint256"
+
+ "github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon-lib/kv/dbutils"
+ "github.com/erigontech/erigon-lib/trie"
+ "github.com/erigontech/erigon-lib/types/accounts"
+)
+
+var (
+ _ StateReader = (*Stateless)(nil)
+ _ StateWriter = (*Stateless)(nil)
+)
+
+// Stateless is the inter-block cache for stateless client prototype, iteration 2
+// It creates the initial state trie during the construction, and then updates it
+// during the execution of block(s)
+type Stateless struct {
+ t *trie.Trie // State trie
+ codeUpdates map[common.Hash][]byte // Lookup index from code hashes to corresponding bytecode
+ blockNr uint64 // Current block number
+ storageUpdates map[common.Hash]map[common.Hash][]byte
+ accountUpdates map[common.Hash]*accounts.Account
+ deleted map[common.Hash]struct{}
+ created map[common.Hash]struct{}
+ trace bool
+}
+
+// NewStateless creates a new instance of Stateless
+// It deserialises the block witness and creates the state trie out of it, checking that the root of the constructed
+// state trie matches the value of `stateRoot` parameter
+func NewStateless(stateRoot common.Hash, blockWitness *trie.Witness, blockNr uint64, trace bool, isBinary bool) (*Stateless, error) {
+ t, err := trie.BuildTrieFromWitness(blockWitness, trace)
+ if err != nil {
+ return nil, err
+ }
+
+ if !isBinary {
+ if t.Hash() != stateRoot {
+ filename := fmt.Sprintf("root_%d.txt", blockNr)
+ f, err := os.Create(filename)
+ if err == nil {
+ defer f.Close()
+ t.Print(f)
+ }
+ return nil, fmt.Errorf("state root mistmatch when creating Stateless2, got %x, expected %x", t.Hash(), stateRoot)
+ }
+ }
+ return &Stateless{
+ t: t,
+ codeUpdates: make(map[common.Hash][]byte),
+ storageUpdates: make(map[common.Hash]map[common.Hash][]byte),
+ accountUpdates: make(map[common.Hash]*accounts.Account),
+ deleted: make(map[common.Hash]struct{}),
+ created: make(map[common.Hash]struct{}),
+ blockNr: blockNr,
+ trace: trace,
+ }, nil
+}
+
+// SetBlockNr changes the block number associated with this
+func (s *Stateless) SetBlockNr(blockNr uint64) {
+ s.blockNr = blockNr
+}
+
+func (s *Stateless) SetStrictHash(strict bool) {
+ s.t.SetStrictHash(strict)
+}
+
+func (s *Stateless) ReadAccountDataForDebug(address common.Address) (*accounts.Account, error) {
+ return s.ReadAccountData(address)
+}
+
+// ReadAccountData is a part of the StateReader interface
+// This implementation attempts to look up account data in the state trie, and fails if it is not found
+func (s *Stateless) ReadAccountData(address common.Address) (*accounts.Account, error) {
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return nil, err
+ }
+ acc, ok := s.t.GetAccount(addrHash[:])
+ if s.trace {
+ fmt.Printf("Stateless: ReadAccountData(address=%x) --> %v\n", address.Bytes(), acc)
+ }
+ if ok {
+ return acc, nil
+ }
+ return nil, nil
+}
+
+// ReadAccountStorage is a part of the StateReader interface
+// This implementation attempts to look up the storage in the state trie, and fails if it is not found
+func (s *Stateless) ReadAccountStorage(address common.Address, incarnation uint64, key *common.Hash) ([]byte, error) {
+ if s.trace {
+ fmt.Printf("Stateless: ReadAccountStorage(address=%x, incarnation=%d, key=%x)\n", address.Bytes(), incarnation, key.Bytes())
+ }
+ seckey, err := common.HashData(key[:])
+ if err != nil {
+ return nil, err
+ }
+
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return nil, err
+ }
+
+ if enc, ok := s.t.Get(dbutils.GenerateCompositeTrieKey(addrHash, seckey)); ok {
+ return enc, nil
+ }
+
+ return nil, nil
+}
+
+// ReadAccountCode is a part of the StateReader interface
+func (s *Stateless) ReadAccountCode(address common.Address, incarnation uint64) (code []byte, err error) {
+ if s.trace {
+ fmt.Printf("Getting code for address %x\n", address)
+ }
+
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return nil, err
+ }
+
+ if code, ok := s.codeUpdates[addrHash]; ok {
+ return code, nil
+ }
+
+ if code, ok := s.t.GetAccountCode(addrHash[:]); ok {
+ return code, nil
+ }
+ return nil, nil
+}
+
+// ReadAccountCodeSize is a part of the StateReader interface
+// This implementation looks the code up in the codeMap, and returns its size
+// It fails if the code is not found in the map
+func (s *Stateless) ReadAccountCodeSize(address common.Address, incarnation uint64) (codeSize int, err error) {
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return 0, err
+ }
+
+ if code, ok := s.codeUpdates[addrHash]; ok {
+ return len(code), nil
+ }
+
+ if code, ok := s.t.GetAccountCode(addrHash[:]); ok {
+ return len(code), nil
+ }
+
+ if codeSize, ok := s.t.GetAccountCodeSize(addrHash[:]); ok {
+ return codeSize, nil
+ }
+
+ return 0, nil
+}
+
+func (s *Stateless) ReadAccountIncarnation(address common.Address) (uint64, error) {
+ return 0, nil
+}
+
+// UpdateAccountData is a part of the StateWriter interface
+// This implementation registers the account update in the `accountUpdates` map
+func (s *Stateless) UpdateAccountData(address common.Address, original, account *accounts.Account) error {
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return err
+ }
+ if s.trace {
+ fmt.Printf("Stateless: UpdateAccountData for address %x, addrHash %x\n", address, addrHash)
+ }
+ s.accountUpdates[addrHash] = account
+ return nil
+}
+
+// DeleteAccount is a part of the StateWriter interface
+// This implementation registers the deletion of the account in two internal maps
+func (s *Stateless) DeleteAccount(address common.Address, original *accounts.Account) error {
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return err
+ }
+ s.accountUpdates[addrHash] = nil
+ s.deleted[addrHash] = struct{}{}
+ if s.trace {
+ fmt.Printf("Stateless: DeleteAccount %x hash %x\n", address, addrHash)
+ }
+ return nil
+}
+
+// UpdateAccountCode is a part of the StateWriter interface
+// This implementation adds the code to the codeMap to make it available for further accesses
+func (s *Stateless) UpdateAccountCode(address common.Address, incarnation uint64, codeHash common.Hash, code []byte) error {
+ s.codeUpdates[codeHash] = code
+
+ if s.trace {
+ fmt.Printf("Stateless: UpdateAccountCode %x codeHash %x\n", address, codeHash)
+ }
+ return nil
+}
+
+// WriteAccountStorage is a part of the StateWriter interface
+// This implementation registeres the change of the account's storage in the internal double map `storageUpdates`
+func (s *Stateless) WriteAccountStorage(address common.Address, incarnation uint64, key *common.Hash, original, value *uint256.Int) error {
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return err
+ }
+
+ v := value.Bytes()
+ m, ok := s.storageUpdates[addrHash]
+ if !ok {
+ m = make(map[common.Hash][]byte)
+ s.storageUpdates[addrHash] = m
+ }
+ seckey, err := common.HashData(key[:])
+ if err != nil {
+ return err
+ }
+ if len(v) > 0 {
+ m[seckey] = v
+ } else {
+ m[seckey] = nil
+ }
+ if s.trace {
+ fmt.Printf("Stateless: WriteAccountStorage %x key %x val %x\n", address, *key, *value)
+ }
+ return nil
+}
+
+// CreateContract is a part of StateWriter interface
+// This implementation registers given address in the internal map `created`
+func (s *Stateless) CreateContract(address common.Address) error {
+ addrHash, err := common.HashData(address[:])
+ if err != nil {
+ return err
+ }
+ if s.trace {
+ fmt.Printf("Stateless: CreateContract %x hash %x\n", address, addrHash)
+ }
+ s.created[addrHash] = struct{}{}
+ return nil
+}
+
+func (s *Stateless) WriteChangeSets() error { return nil }
+
+func (s *Stateless) WriteHistory() error { return nil }
+
+// CheckRoot finalises the execution of a block and computes the resulting state root
+func (s *Stateless) CheckRoot(expected common.Hash) error {
+ h := s.Finalize()
+ fmt.Printf("trie root after stateless exec : %x , expected trie root: %x\n", h, expected)
+ if h != expected {
+ filename := fmt.Sprintf("root_%d.txt", s.blockNr)
+ f, err := os.Create(filename)
+ if err == nil {
+ defer f.Close()
+ s.t.Print(f)
+ }
+ return fmt.Errorf("final root: %x, expected: %x", h, expected)
+ }
+
+ return nil
+}
+
+// Finalize the execution of a block and computes the resulting state root
+func (s *Stateless) Finalize() common.Hash {
+ // The following map is to prevent repeated clearouts of the storage
+ alreadyCreated := make(map[common.Hash]struct{})
+ // New contracts are being created at these addresses. Therefore, we need to clear the storage items
+ // that might be remaining in the trie and figure out the next incarnations
+ for addrHash := range s.created {
+ // Prevent repeated storage clearouts
+ if _, ok := alreadyCreated[addrHash]; ok {
+ continue
+ }
+ alreadyCreated[addrHash] = struct{}{}
+ if account, ok := s.accountUpdates[addrHash]; ok && account != nil {
+ account.Root = trie.EmptyRoot
+ }
+ // The only difference between Delete and DeleteSubtree is that Delete would delete accountNode too,
+ // wherewas DeleteSubtree will keep the accountNode, but will make the storage sub-trie empty
+ s.t.DeleteSubtree(addrHash[:])
+ }
+ for addrHash, account := range s.accountUpdates {
+ if account != nil {
+ s.t.UpdateAccount(addrHash[:], account)
+ } else {
+ s.t.Delete(addrHash[:])
+ }
+ }
+ for addrHash, m := range s.storageUpdates {
+ if _, ok := s.deleted[addrHash]; ok {
+ // Deleted contracts will be dealth with later, in the next loop
+ continue
+ }
+
+ for keyHash, v := range m {
+ cKey := dbutils.GenerateCompositeTrieKey(addrHash, keyHash)
+ if len(v) > 0 {
+ s.t.Update(cKey, v)
+ } else {
+ s.t.Delete(cKey)
+ }
+ }
+ if account, ok := s.accountUpdates[addrHash]; ok && account != nil {
+ ok, root := s.t.DeepHash(addrHash[:])
+ if ok {
+ account.Root = root
+ } else {
+ account.Root = trie.EmptyRoot
+ }
+ }
+ }
+ // For the contracts that got deleted
+ for addrHash := range s.deleted {
+ if _, ok := s.created[addrHash]; ok {
+ // In some rather artificial circumstances, an account can be recreated after having been self-destructed
+ // in the same block. It can only happen when contract is introduced in the genesis state with nonce 0
+ // rather than created by a transaction (in that case, its starting nonce is 1). The self-destructed
+ // contract actually gets removed from the state only at the end of the block, so if its nonce is not 0,
+ // it will prevent any re-creation within the same block. However, if the contract is introduced in
+ // the genesis state, its nonce is 0, and that means it can be self-destructed, and then re-created,
+ // all in the same block. In such cases, we must preserve storage modifications happening after the
+ // self-destruction
+ continue
+ }
+ if account, ok := s.accountUpdates[addrHash]; ok && account != nil {
+ account.Root = trie.EmptyRoot
+ }
+ s.t.DeleteSubtree(addrHash[:])
+ }
+
+ s.storageUpdates = make(map[common.Hash]map[common.Hash][]byte)
+ s.accountUpdates = make(map[common.Hash]*accounts.Account)
+ s.deleted = make(map[common.Hash]struct{})
+ s.created = make(map[common.Hash]struct{})
+
+ return s.t.Hash()
+}
+
+func (s *Stateless) GetTrie() *trie.Trie {
+ return s.t
+}
diff --git a/core/state/triedb_state.go b/core/state/triedb_state.go
new file mode 100644
index 00000000000..6148ffeedd8
--- /dev/null
+++ b/core/state/triedb_state.go
@@ -0,0 +1,920 @@
+package state
+
+import (
+ "bytes"
+ "encoding/binary"
+ "io"
+ "sort"
+ "sync"
+ "sync/atomic"
+
+ "github.com/erigontech/erigon-lib/common"
+ libcommon "github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon-lib/common/length"
+ "github.com/erigontech/erigon-lib/crypto"
+ "github.com/erigontech/erigon-lib/kv/dbutils"
+ "github.com/erigontech/erigon-lib/trie"
+ "github.com/erigontech/erigon-lib/types/accounts"
+ witnesstypes "github.com/erigontech/erigon-lib/types/witness"
+ "github.com/holiman/uint256"
+)
+
+// Buffer is a structure holding updates, deletes, and reads registered within one change period
+// A change period can be transaction within a block, or a block within group of blocks
+type Buffer struct {
+ codeReads map[libcommon.Hash]witnesstypes.CodeWithHash
+ codeSizeReads map[libcommon.Hash]libcommon.Hash
+ codeUpdates map[libcommon.Hash][]byte
+ // storageUpdates structure collects the effects of the block (or transaction) execution. It does not necessarily
+ // include all the intermediate reads and write that happened. For example, if the storage of some contract has
+ // been modified, and then the contract has subsequently self-destructed, this structure will not contain any
+ // keys related to the storage of this contract, because they are irrelevant for the final state
+ storageUpdates map[libcommon.Hash]map[libcommon.Hash][]byte
+ storageIncarnation map[libcommon.Hash]uint64
+ // storageReads structure collects all the keys of items that have been modified (or also just read, if the
+ // tds.resolveReads flag is turned on, which happens during the generation of block witnesses).
+ // Even if the final results of the execution do not include some items, they will still be present in this structure.
+ // For example, if the storage of some contract has been modified, and then the contract has subsequently self-destructed,
+ // this structure will contain all the keys that have been modified or deleted prior to the self-destruction.
+ // It is important to keep them because they will be used to apply changes to the trie one after another.
+ // There is a potential for optimisation - we may actually skip all the intermediate modification of the trie if
+ // we know that in the end, the entire storage will be dropped. However, this optimisation has not yet been
+ // implemented.
+ storageReads map[common.StorageKey][]byte
+ // accountUpdates structure collects the effects of the block (or transaxction) execution.
+ accountUpdates map[libcommon.Hash]witnesstypes.AccountWithAddress
+ // accountReads structure collects all the address hashes of the accounts that have been modified (or also just read,
+ // if tds.resolveReads flag is turned on, which happens during the generation of block witnesses).
+ accountReads map[libcommon.Hash]libcommon.Address
+ accountReadsIncarnation map[libcommon.Hash]uint64
+ deleted map[libcommon.Hash]libcommon.Address
+ created map[libcommon.Hash]libcommon.Address
+}
+
+// Prepares buffer for work or clears previous data
+func (b *Buffer) initialise() {
+ b.codeReads = make(map[libcommon.Hash]witnesstypes.CodeWithHash)
+ b.codeSizeReads = make(map[libcommon.Hash]libcommon.Hash)
+ b.codeUpdates = make(map[libcommon.Hash][]byte)
+ b.storageUpdates = make(map[libcommon.Hash]map[libcommon.Hash][]byte)
+ b.storageIncarnation = make(map[libcommon.Hash]uint64)
+ b.storageReads = make(map[common.StorageKey][]byte)
+ b.accountUpdates = make(map[libcommon.Hash]witnesstypes.AccountWithAddress)
+ b.accountReads = make(map[libcommon.Hash]libcommon.Address)
+ b.accountReadsIncarnation = make(map[libcommon.Hash]uint64)
+ b.deleted = make(map[libcommon.Hash]libcommon.Address)
+ b.created = make(map[libcommon.Hash]libcommon.Address)
+}
+
+// Replaces account pointer with pointers to the copies
+func (b *Buffer) detachAccounts() {
+ for addrHash, accountWithAddress := range b.accountUpdates {
+ address := accountWithAddress.Address
+ account := accountWithAddress.Account
+ if account != nil {
+ b.accountUpdates[addrHash] = witnesstypes.AccountWithAddress{Address: address, Account: account.SelfCopy()}
+ }
+ }
+}
+
+// Merges the content of another buffer into this one
+func (b *Buffer) merge(other *Buffer) {
+ for addrHash, codeWithHash := range other.codeReads {
+ b.codeReads[addrHash] = codeWithHash
+ }
+
+ for addrHash, code := range other.codeUpdates {
+ b.codeUpdates[addrHash] = code
+ }
+
+ for address, codeHash := range other.codeSizeReads {
+ b.codeSizeReads[address] = codeHash
+ }
+
+ for addrHash := range other.deleted {
+ b.deleted[addrHash] = other.deleted[addrHash]
+ delete(b.storageUpdates, addrHash)
+ delete(b.storageIncarnation, addrHash)
+ delete(b.codeUpdates, addrHash)
+ }
+ for addrHash := range other.created {
+ b.created[addrHash] = other.created[addrHash]
+ delete(b.storageUpdates, addrHash)
+ delete(b.storageIncarnation, addrHash)
+ }
+ for addrHash, om := range other.storageUpdates {
+ m, ok := b.storageUpdates[addrHash]
+ if !ok {
+ m = make(map[libcommon.Hash][]byte)
+ b.storageUpdates[addrHash] = m
+ }
+ for keyHash, v := range om {
+ m[keyHash] = v
+ }
+ }
+ for addrHash, incarnation := range other.storageIncarnation {
+ b.storageIncarnation[addrHash] = incarnation
+ }
+ for storageKey := range other.storageReads {
+ b.storageReads[storageKey] = other.storageReads[storageKey]
+ }
+ for addrHash, accountAddr := range other.accountUpdates {
+ b.accountUpdates[addrHash] = accountAddr
+ }
+ for addrHash := range other.accountReads {
+ b.accountReads[addrHash] = other.accountReads[addrHash]
+ }
+ for addrHash, incarnation := range other.accountReadsIncarnation {
+ b.accountReadsIncarnation[addrHash] = incarnation
+ }
+}
+
+// TrieDbState implements StateReader by wrapping a trie and a database, where trie acts as a cache for the database
+type TrieDbState struct {
+ t *trie.Trie
+ tMu *sync.Mutex
+ StateReader StateReader
+ rl *trie.RetainList
+ blockNr uint64
+ buffers []*Buffer
+ aggregateBuffer *Buffer // Merge of all buffers
+ currentBuffer *Buffer
+ resolveReads bool
+ retainListBuilder *trie.RetainListBuilder
+ hashBuilder *trie.HashBuilder
+ incarnationMap map[libcommon.Address]uint64 // Temporary map of incarnation for the cases when contracts are deleted and recreated within 1 block
+}
+
+func NewTrieDbState(root libcommon.Hash, blockNr uint64, stateReader StateReader) *TrieDbState {
+ t := trie.New(root)
+ tds := &TrieDbState{
+ t: t,
+ tMu: new(sync.Mutex),
+ StateReader: stateReader,
+ blockNr: blockNr,
+ retainListBuilder: trie.NewRetainListBuilder(),
+ hashBuilder: trie.NewHashBuilder(false),
+ incarnationMap: make(map[libcommon.Address]uint64),
+ }
+ return tds
+}
+
+func (tds *TrieDbState) SetRetainList(rl *trie.RetainList) {
+ tds.rl = rl
+}
+
+func (tds *TrieDbState) SetTrie(tr *trie.Trie) {
+ tds.t = tr
+}
+
+func (tds *TrieDbState) SetResolveReads(rr bool) {
+ tds.resolveReads = rr
+}
+
+func (tds *TrieDbState) Copy() *TrieDbState {
+ tds.tMu.Lock()
+ tcopy := *tds.t
+ tds.tMu.Unlock()
+
+ n := tds.getBlockNr()
+ cpy := TrieDbState{
+ t: &tcopy,
+ tMu: new(sync.Mutex),
+ blockNr: n,
+ hashBuilder: trie.NewHashBuilder(false),
+ incarnationMap: make(map[libcommon.Address]uint64),
+ }
+ return &cpy
+}
+
+func (tds *TrieDbState) Trie() *trie.Trie {
+ return tds.t
+}
+
+func (tds *TrieDbState) StartNewBuffer() {
+ if tds.currentBuffer != nil {
+ if tds.aggregateBuffer == nil {
+ tds.aggregateBuffer = &Buffer{}
+ tds.aggregateBuffer.initialise()
+ }
+ tds.aggregateBuffer.merge(tds.currentBuffer)
+ tds.currentBuffer.detachAccounts()
+ }
+ tds.currentBuffer = &Buffer{}
+ tds.currentBuffer.initialise()
+ tds.buffers = append(tds.buffers, tds.currentBuffer)
+}
+
+func (tds *TrieDbState) WithNewBuffer() *TrieDbState {
+ aggregateBuffer := &Buffer{}
+ aggregateBuffer.initialise()
+
+ currentBuffer := &Buffer{}
+ currentBuffer.initialise()
+
+ buffers := []*Buffer{currentBuffer}
+
+ tds.tMu.Lock()
+ t := &TrieDbState{
+ t: tds.t,
+ tMu: tds.tMu,
+ blockNr: tds.getBlockNr(),
+ buffers: buffers,
+ aggregateBuffer: aggregateBuffer,
+ currentBuffer: currentBuffer,
+ resolveReads: tds.resolveReads,
+ retainListBuilder: tds.retainListBuilder,
+ hashBuilder: trie.NewHashBuilder(false),
+ incarnationMap: make(map[libcommon.Address]uint64),
+ }
+ tds.tMu.Unlock()
+
+ return t
+}
+
+func (tds *TrieDbState) WithLastBuffer() *TrieDbState {
+ tds.tMu.Lock()
+ aggregateBuffer := &Buffer{}
+ aggregateBuffer.initialise()
+ currentBuffer := tds.currentBuffer
+ buffers := []*Buffer{currentBuffer}
+ tds.tMu.Unlock()
+
+ return &TrieDbState{
+ t: tds.t,
+ tMu: tds.tMu,
+ blockNr: tds.getBlockNr(),
+ buffers: buffers,
+ aggregateBuffer: aggregateBuffer,
+ currentBuffer: currentBuffer,
+ resolveReads: tds.resolveReads,
+ retainListBuilder: tds.retainListBuilder.Copy(),
+ hashBuilder: trie.NewHashBuilder(false),
+ incarnationMap: make(map[libcommon.Address]uint64),
+ }
+}
+
+func (tds *TrieDbState) LastRoot() libcommon.Hash {
+ if tds == nil || tds.tMu == nil {
+ return libcommon.Hash{}
+ }
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+ return tds.t.Hash()
+}
+
+// UpdateStateTrie assumes that the state trie is already fully resolved, i.e. any operations
+// will find necessary data inside the trie.
+func (tds *TrieDbState) UpdateStateTrie() ([]libcommon.Hash, error) {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+
+ roots, err := tds.updateTrieRoots(true)
+ tds.ClearUpdates()
+ return roots, err
+}
+
+func (tds *TrieDbState) PrintTrie(w io.Writer) {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+ tds.t.Print(w)
+}
+
+func (tds *TrieDbState) buildPlainStorageReads() ([][]byte, [][]byte) {
+ storagePlainKeys := make([][]byte, 0, len(tds.aggregateBuffer.storageReads))
+ storageHashedKeys := make([][]byte, 0, len(tds.aggregateBuffer.storageReads))
+
+ for storageHashedKey, storagePlainKey := range tds.aggregateBuffer.storageReads {
+ // to prevent variable capture in Go 1.21
+ storagePlainKeyCopy := make([]byte, len(storagePlainKey))
+ copy(storagePlainKeyCopy, storagePlainKey)
+ storageHashedKeyCopy := make([]byte, len(storageHashedKey))
+ copy(storageHashedKeyCopy, storageHashedKey[:])
+ storagePlainKeys = append(storagePlainKeys, storagePlainKeyCopy)
+ storageHashedKeys = append(storageHashedKeys, storageHashedKeyCopy)
+ }
+
+ // Create a slice of indices to track original positions
+ indices := make([]int, len(storagePlainKeys))
+ for i := range indices {
+ indices[i] = i
+ }
+
+ // Sort indices based on accountAddresses
+ sort.SliceStable(indices, func(i, j int) bool {
+ return bytes.Compare(storagePlainKeys[indices[i]], storagePlainKeys[indices[j]]) < 0
+ })
+
+ // Apply the sorted order to accountAddresses and accountAddressHashes
+ sortedStoragePlainKeys := make([][]byte, len(storagePlainKeys))
+ sortedStorageHashedKeys := make([][]byte, len(storageHashedKeys))
+ for i, idx := range indices {
+ sortedStoragePlainKeys[i] = storagePlainKeys[idx]
+ sortedStorageHashedKeys[i] = storageHashedKeys[idx]
+ }
+ return sortedStorageHashedKeys, sortedStoragePlainKeys
+}
+
+// BuildStorageReads builds a sorted list of all storage key hashes that were modified
+// (or also just read, if tds.resolveReads flag is turned on) within the
+// period for which we are aggregating updates. It includes the keys of items that
+// were nullified by subsequent updates - best example is the
+// self-destruction of a contract, which nullifies all previous
+// modifications of the contract's storage. In such case, all previously modified storage
+// item updates would be inclided.
+func (tds *TrieDbState) BuildStorageReads() common.StorageKeys {
+ storageTouches := common.StorageKeys{}
+ for storageKey := range tds.aggregateBuffer.storageReads {
+ storageTouches = append(storageTouches, storageKey)
+ }
+ sort.Sort(storageTouches)
+ return storageTouches
+}
+
+// buildStorageWrites builds a sorted list of all storage key hashes that were modified within the
+// period for which we are aggregating updates. It skips the updates that
+// were nullified by subsequent updates - best example is the
+// self-destruction of a contract, which nullifies all previous
+// modifications of the contract's storage. In such case, no storage
+// item updates would be inclided.
+func (tds *TrieDbState) buildStorageWrites() (common.StorageKeys, [][]byte) {
+ storageTouches := common.StorageKeys{}
+ for addrHash, m := range tds.aggregateBuffer.storageUpdates {
+ for keyHash := range m {
+ var storageKey common.StorageKey
+ copy(storageKey[:], addrHash[:])
+ binary.BigEndian.PutUint64(storageKey[length.Hash:], tds.aggregateBuffer.storageIncarnation[addrHash])
+ copy(storageKey[length.Hash+length.Incarnation:], keyHash[:])
+ storageTouches = append(storageTouches, storageKey)
+ }
+ }
+ sort.Sort(storageTouches)
+ var addrHash libcommon.Hash
+ var keyHash libcommon.Hash
+ var values = make([][]byte, len(storageTouches))
+ for i, storageKey := range storageTouches {
+ copy(addrHash[:], storageKey[:])
+ copy(keyHash[:], storageKey[length.Hash+length.Incarnation:])
+ values[i] = tds.aggregateBuffer.storageUpdates[addrHash][keyHash]
+ }
+ return storageTouches, values
+}
+
+// Populate pending block proof so that it will be sufficient for accessing all storage slots in storageTouches
+func (tds *TrieDbState) PopulateStorageBlockProof(storageTouches common.StorageKeys) error { //nolint
+ for _, storageKey := range storageTouches {
+ addr, _, hash := dbutils.ParseCompositeStorageKey(storageKey[:])
+ key := dbutils.GenerateCompositeTrieKey(addr, hash)
+ tds.retainListBuilder.AddStorageTouch(key)
+ }
+ return nil
+}
+
+func (tds *TrieDbState) BuildCodeTouches() map[libcommon.Hash]witnesstypes.CodeWithHash {
+ return tds.aggregateBuffer.codeReads
+}
+
+func (tds *TrieDbState) buildCodeSizeTouches() map[libcommon.Hash]libcommon.Hash {
+ return tds.aggregateBuffer.codeSizeReads
+}
+
+// BuildAccountReads builds a sorted list of all address hashes that were modified
+// (or also just read, if tds.resolveReads flags is turned one) within the
+// period for which we are aggregating update
+func (tds *TrieDbState) BuildAccountReads() common.Hashes {
+ accountTouches := common.Hashes{}
+ for addrHash := range tds.aggregateBuffer.accountReads {
+ accountTouches = append(accountTouches, addrHash)
+ }
+ sort.Sort(accountTouches)
+ return accountTouches
+}
+
+func (tds *TrieDbState) buildAccountAddressReads() ([][]byte, [][]byte) {
+ accountAddressHashes := make([][]byte, 0, len(tds.aggregateBuffer.accountReads))
+ accountAddresses := make([][]byte, 0, len(tds.aggregateBuffer.accountReads))
+ for addrHash, address := range tds.aggregateBuffer.accountReads {
+ computedAddrHash := crypto.Keccak256(address.Bytes())
+ if !bytes.Equal(addrHash[:], computedAddrHash) {
+ panic("could not reproduce addrHash found in the map")
+ }
+ accountAddresses = append(accountAddresses, address.Bytes())
+ accountAddressHashes = append(accountAddressHashes, addrHash.Bytes())
+ }
+
+ // Create a slice of indices to track original positions
+ indices := make([]int, len(accountAddresses))
+ for i := range indices {
+ indices[i] = i
+ }
+
+ // Sort indices based on accountAddresses
+ sort.SliceStable(indices, func(i, j int) bool {
+ return bytes.Compare(accountAddresses[indices[i]], accountAddresses[indices[j]]) < 0
+ })
+
+ // Apply the sorted order to accountAddresses and accountAddressHashes
+ sortedAccountAddresses := make([][]byte, len(accountAddresses))
+ sortedAccountAddressHashes := make([][]byte, len(accountAddressHashes))
+ for i, idx := range indices {
+ sortedAccountAddresses[i] = accountAddresses[idx]
+ sortedAccountAddressHashes[i] = accountAddressHashes[idx]
+ }
+
+ // Check if sorting is correct
+ for i := 0; i < len(sortedAccountAddresses); i++ {
+ addrHash := sortedAccountAddressHashes[i]
+ accountAddress := sortedAccountAddresses[i]
+ computedHash := crypto.Keccak256(accountAddress)
+ if !bytes.Equal(addrHash, computedHash) {
+ panic("sorting is not correct, this should not happen")
+ }
+ }
+
+ return sortedAccountAddressHashes, sortedAccountAddresses
+}
+
+// buildAccountWrites builds a sorted list of all address hashes that were modified within the
+// period for which we are aggregating updates.
+func (tds *TrieDbState) buildAccountWrites() (common.Hashes, []*accounts.Account, [][]byte) {
+ accountTouches := common.Hashes{}
+ for addrHash := range tds.aggregateBuffer.accountUpdates {
+ if _, ok := tds.aggregateBuffer.deleted[addrHash]; ok {
+ // This adds an extra entry that wipes out the storage of the accout in the stream
+ accountTouches = append(accountTouches, addrHash)
+ } else if _, ok1 := tds.aggregateBuffer.created[addrHash]; ok1 {
+ // This adds an extra entry that wipes out the storage of the accout in the stream
+ accountTouches = append(accountTouches, addrHash)
+ }
+ accountTouches = append(accountTouches, addrHash)
+ }
+ sort.Sort(accountTouches)
+ aValues := make([]*accounts.Account, len(accountTouches))
+ aCodes := make([][]byte, len(accountTouches))
+ for i, addrHash := range accountTouches {
+ if i < len(accountTouches)-1 && addrHash == accountTouches[i+1] {
+ aValues[i] = nil // Entry that would wipe out existing storage
+ } else {
+ a := tds.aggregateBuffer.accountUpdates[addrHash]
+ if a.Account != nil {
+ if _, ok := tds.aggregateBuffer.storageUpdates[addrHash]; ok {
+ var ac accounts.Account
+ ac.Copy(a.Account)
+ ac.Root = trie.EmptyRoot
+ a.Account = &ac
+ }
+ }
+ aValues[i] = a.Account
+ if code, ok := tds.aggregateBuffer.codeUpdates[addrHash]; ok {
+ aCodes[i] = code
+ }
+ }
+ }
+ return accountTouches, aValues, aCodes
+}
+
+func (tds *TrieDbState) PopulateAccountBlockProof(accountTouches common.Hashes) {
+ for _, addrHash := range accountTouches {
+ a := addrHash
+ tds.retainListBuilder.AddTouch(a[:])
+ }
+}
+
+// ExtractTouches returns two lists of keys - for accounts and storage items correspondingly
+// Each list is the collection of keys that have been "touched" (inserted, updated, or simply accessed)
+// since the last invocation of `ExtractTouches`.
+func (tds *TrieDbState) ExtractTouches() (accountTouches [][]byte, storageTouches [][]byte) {
+ return tds.retainListBuilder.ExtractTouches()
+}
+
+func (tds *TrieDbState) GetRetainList() *trie.RetainList {
+ return tds.retainListBuilder.Build(false)
+}
+
+// Get list of account and storage touches
+// First come the account touches then the storage touches
+func (tds *TrieDbState) GetTouchedPlainKeys() (plainKeys [][]byte, hashedKeys [][]byte) {
+ // Aggregating the current buffer, if any
+ if tds.currentBuffer != nil {
+ if tds.aggregateBuffer == nil {
+ tds.aggregateBuffer = &Buffer{}
+ tds.aggregateBuffer.initialise()
+ }
+ tds.aggregateBuffer.merge(tds.currentBuffer)
+ }
+ if tds.aggregateBuffer == nil {
+ return nil, nil
+ }
+ accountHashTouches, accountAddressTouches := tds.buildAccountAddressReads()
+ storageHashTouches, storagePlainKeyTouches := tds.buildPlainStorageReads()
+ plainKeys = append(accountAddressTouches, storagePlainKeyTouches...)
+ hashedKeys = append(accountHashTouches, storageHashTouches...)
+ return plainKeys, hashedKeys
+
+}
+
+func (tds *TrieDbState) ResolveBuffer() {
+ if tds.currentBuffer != nil {
+ if tds.aggregateBuffer == nil {
+ tds.aggregateBuffer = &Buffer{}
+ tds.aggregateBuffer.initialise()
+ }
+ tds.aggregateBuffer.merge(tds.currentBuffer)
+ }
+}
+
+// forward is `true` if the function is used to progress the state forward (by adding blocks)
+// forward is `false` if the function is used to rewind the state (for reorgs, for example)
+func (tds *TrieDbState) updateTrieRoots(forward bool) ([]libcommon.Hash, error) {
+ // Perform actual updates on the tries, and compute one trie root per buffer
+ // These roots can be used to populate receipt.PostState on pre-Byzantium
+ roots := make([]libcommon.Hash, len(tds.buffers))
+ for i, b := range tds.buffers {
+ // For the contracts that got deleted, we clear the storage
+ for addrHash := range b.deleted {
+ // The only difference between Delete and DeleteSubtree is that Delete would delete accountNode too,
+ // wherewas DeleteSubtree will keep the accountNode, but will make the storage sub-trie empty
+ tds.t.DeleteSubtree(addrHash[:])
+ }
+ // New contracts are being created at these addresses. Therefore, we need to clear the storage items
+ // that might be remaining in the trie and figure out the next incarnations
+ for addrHash := range b.created {
+ // The only difference between Delete and DeleteSubtree is that Delete would delete accountNode too,
+ // wherewas DeleteSubtree will keep the accountNode, but will make the storage sub-trie empty
+ tds.t.DeleteSubtree(addrHash[:])
+ }
+
+ for addrHash, accountWithAddress := range b.accountUpdates {
+ if accountWithAddress.Account != nil {
+ //fmt.Println("updateTrieRoots b.accountUpdates", addrHash.String(), account.Incarnation)
+ tds.t.UpdateAccount(addrHash[:], accountWithAddress.Account)
+ } else {
+ tds.t.Delete(addrHash[:])
+ }
+ }
+
+ for addrHash, newCode := range b.codeUpdates {
+ if err := tds.t.UpdateAccountCode(addrHash[:], newCode); err != nil {
+ return nil, err
+ }
+ }
+ for addrHash, m := range b.storageUpdates {
+ for keyHash, v := range m {
+ cKey := dbutils.GenerateCompositeTrieKey(addrHash, keyHash)
+ if len(v) > 0 {
+ //fmt.Printf("Update storage trie addrHash %x, keyHash %x: %x\n", addrHash, keyHash, v)
+ if forward {
+ tds.t.Update(cKey, v)
+ } else {
+ // If rewinding, it might not be possible to execute storage item update.
+ // If we rewind from the state where a contract does not exist anymore (it was self-destructed)
+ // to the point where it existed (with storage), then rewinding to the point of existence
+ // will not bring back the full storage trie. Instead there will be one hashNode.
+ // So we probe for this situation first
+ if _, ok := tds.t.Get(cKey); ok {
+ tds.t.Update(cKey, v)
+ }
+ }
+ } else {
+ if forward {
+ tds.t.Delete(cKey)
+ } else {
+ // If rewinding, it might not be possible to execute storage item update.
+ // If we rewind from the state where a contract does not exist anymore (it was self-destructed)
+ // to the point where it existed (with storage), then rewinding to the point of existence
+ // will not bring back the full storage trie. Instead there will be one hashNode.
+ // So we probe for this situation first
+ if _, ok := tds.t.Get(cKey); ok {
+ tds.t.Delete(cKey)
+ }
+ }
+ }
+ }
+
+ if accountWithAddress, ok := b.accountUpdates[addrHash]; ok && accountWithAddress.Account != nil {
+ ok, root := tds.t.DeepHash(addrHash[:])
+ if ok {
+ accountWithAddress.Account.Root = root
+ //fmt.Printf("(b)Set %x root for addrHash %x\n", root, addrHash)
+ } else {
+ //fmt.Printf("(b)Set empty root for addrHash %x\n", addrHash)
+ accountWithAddress.Account.Root = trie.EmptyRoot
+ }
+ }
+ }
+ roots[i] = tds.t.Hash()
+ }
+
+ return roots, nil
+}
+
+func (tds *TrieDbState) ClearUpdates() {
+ tds.buffers = nil
+ tds.currentBuffer = nil
+ tds.aggregateBuffer = nil
+}
+
+func (tds *TrieDbState) SetBlockNr(blockNr uint64) {
+ tds.setBlockNr(blockNr)
+}
+
+func (tds *TrieDbState) GetBlockNr() uint64 {
+ return tds.getBlockNr()
+}
+
+func (tds *TrieDbState) GetAccount(addrHash libcommon.Hash) (*accounts.Account, bool) {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+ acc, ok := tds.t.GetAccount(addrHash[:])
+ return acc, ok
+}
+
+func (tds *TrieDbState) ReadAccountDataForDebug(address libcommon.Address) (*accounts.Account, error) {
+ return tds.ReadAccountData(address)
+}
+
+func (tds *TrieDbState) ReadAccountData(address libcommon.Address) (*accounts.Account, error) {
+ var account *accounts.Account
+
+ addrHash, err := libcommon.HashData(address[:])
+ if err != nil {
+ return nil, err
+ }
+
+ account, ok := tds.GetAccount(addrHash)
+ if !ok {
+ account, err = tds.StateReader.ReadAccountData(address)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if tds.resolveReads {
+ tds.currentBuffer.accountReads[addrHash] = address
+ if account != nil {
+ tds.currentBuffer.accountReadsIncarnation[addrHash] = account.Incarnation
+ }
+ }
+ return account, nil
+}
+
+func (tds *TrieDbState) ReadAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash) ([]byte, error) {
+ addrHash := libcommon.Hash(crypto.Keccak256(address.Bytes()))
+ if tds.currentBuffer != nil {
+ if _, ok := tds.currentBuffer.deleted[addrHash]; ok {
+ return nil, nil
+ }
+ }
+ if tds.aggregateBuffer != nil {
+ if _, ok := tds.aggregateBuffer.deleted[addrHash]; ok {
+ return nil, nil
+ }
+ }
+ seckey, err := libcommon.HashData(key.Bytes())
+ if err != nil {
+ return nil, err
+ }
+
+ storagePlainKey := dbutils.GenerateStoragePlainKey(address, *key)
+
+ if tds.resolveReads {
+ var storageKey common.StorageKey
+ copy(storageKey[:], dbutils.GenerateCompositeStorageKey(addrHash, incarnation, seckey))
+ tds.currentBuffer.storageReads[storageKey] = storagePlainKey
+ }
+
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+ enc, ok := tds.t.Get(dbutils.GenerateCompositeTrieKey(addrHash, seckey))
+ if !ok {
+ enc, err := tds.StateReader.ReadAccountStorage(address, incarnation, key)
+ if err != nil {
+ return nil, err
+ }
+ return enc, nil
+ }
+
+ return enc, nil
+}
+
+func (tds *TrieDbState) readAccountCodeFromTrie(addrHash []byte) ([]byte, bool) {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+ return tds.t.GetAccountCode(addrHash)
+}
+
+func (tds *TrieDbState) readAccountCodeSizeFromTrie(addrHash []byte) (int, bool) {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+ return tds.t.GetAccountCodeSize(addrHash)
+}
+
+func (tds *TrieDbState) ReadAccountCode(address libcommon.Address, incarnation uint64) (code []byte, err error) {
+ addrHash := libcommon.Hash(crypto.Keccak256(address.Bytes()))
+
+ if cached, ok := tds.readAccountCodeFromTrie(addrHash[:]); ok {
+ code, err = cached, nil
+ } else {
+ code, err = tds.StateReader.ReadAccountCode(address, incarnation)
+ }
+ if tds.resolveReads {
+ addrHash, err1 := libcommon.HashData(address[:])
+ if err1 != nil {
+ return nil, err
+ }
+ tds.currentBuffer.accountReads[addrHash] = address
+ // we have to be careful, because the code might change
+ // during the block executuion, so we are always
+ // storing the latest code hash
+ codeHash := crypto.Keccak256Hash(code)
+ tds.currentBuffer.codeReads[addrHash] = witnesstypes.CodeWithHash{Code: code, CodeHash: codeHash}
+ tds.retainListBuilder.ReadCode(codeHash, code)
+ }
+ return code, err
+}
+
+func (tds *TrieDbState) ReadAccountCodeSize(address libcommon.Address, incarnation uint64) (codeSize int, err error) {
+ addrHash := libcommon.Hash(crypto.Keccak256(address.Bytes()))
+ if cached, ok := tds.readAccountCodeSizeFromTrie(addrHash[:]); ok {
+ return cached, nil
+ } else {
+ codeSize, err = tds.StateReader.ReadAccountCodeSize(address, incarnation)
+ if err != nil {
+ return 0, err
+ }
+ }
+ if tds.resolveReads {
+ // We will need to read the code explicitly to make sure code is in the witness
+ code, err := tds.ReadAccountCode(address, incarnation)
+ if err != nil {
+ return 0, err
+ }
+
+ codeHash := crypto.Keccak256Hash(code)
+
+ addrHash, err1 := libcommon.HashData(address[:])
+ if err1 != nil {
+ return 0, err1
+ }
+ tds.currentBuffer.accountReads[addrHash] = address
+ // we have to be careful, because the code might change
+ // during the block executuion, so we are always
+ // storing the latest code hash
+ tds.currentBuffer.codeSizeReads[addrHash] = codeHash
+ // FIXME: support codeSize in witnesses if makes sense
+ tds.retainListBuilder.ReadCode(codeHash, code)
+ }
+ return codeSize, nil
+}
+
+func (tds *TrieDbState) ReadAccountIncarnation(address libcommon.Address) (uint64, error) {
+ if inc, ok := tds.incarnationMap[address]; ok {
+ return inc, nil
+ }
+ inc, err := tds.StateReader.ReadAccountIncarnation(address)
+ if err != nil {
+ return 0, err
+ } else {
+ return inc, nil
+ }
+}
+
+type TrieStateWriter struct {
+ tds *TrieDbState
+}
+
+func (tds *TrieDbState) TrieStateWriter() *TrieStateWriter {
+ return &TrieStateWriter{tds: tds}
+}
+
+func (tds *TrieStateWriter) WriteChangeSets() error { return nil }
+
+func (tds *TrieStateWriter) WriteHistory() error { return nil }
+
+func (tsw *TrieStateWriter) UpdateAccountData(address libcommon.Address, original, account *accounts.Account) error {
+ addrHash := libcommon.Hash(crypto.Keccak256(address.Bytes()))
+ tsw.tds.currentBuffer.accountUpdates[addrHash] = witnesstypes.AccountWithAddress{Address: address, Account: account}
+ tsw.tds.currentBuffer.accountReads[addrHash] = address
+ if original != nil {
+ tsw.tds.currentBuffer.accountReadsIncarnation[addrHash] = original.Incarnation
+ }
+ return nil
+}
+
+func (tsw *TrieStateWriter) DeleteAccount(address libcommon.Address, original *accounts.Account) error {
+ addrHash := libcommon.Hash(crypto.Keccak256(address.Bytes()))
+ tsw.tds.currentBuffer.accountUpdates[addrHash] = witnesstypes.AccountWithAddress{Address: address, Account: original} // TODO: might be needed to use *AccountWithAddress to point to nil
+ tsw.tds.currentBuffer.accountReads[addrHash] = address
+ if original != nil {
+ tsw.tds.currentBuffer.accountReadsIncarnation[addrHash] = original.Incarnation
+ }
+ delete(tsw.tds.currentBuffer.storageUpdates, addrHash)
+ delete(tsw.tds.currentBuffer.storageIncarnation, addrHash)
+ delete(tsw.tds.currentBuffer.codeUpdates, addrHash)
+ tsw.tds.currentBuffer.deleted[addrHash] = address
+ if original.Incarnation > 0 {
+ tsw.tds.incarnationMap[address] = original.Incarnation
+ }
+ return nil
+}
+
+func (tsw *TrieStateWriter) UpdateAccountCode(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash, code []byte) error {
+ if tsw.tds.resolveReads {
+ tsw.tds.retainListBuilder.CreateCode(codeHash)
+ }
+ addrHash, err := libcommon.HashData(address.Bytes())
+ if err != nil {
+ return err
+ }
+ tsw.tds.currentBuffer.codeUpdates[addrHash] = code
+ return nil
+}
+
+func (tsw *TrieStateWriter) WriteAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash, original, value *uint256.Int) error {
+ addrHash := libcommon.Hash(crypto.Keccak256(address.Bytes()))
+
+ v := value.Bytes()
+ m, ok := tsw.tds.currentBuffer.storageUpdates[addrHash]
+ if !ok {
+ m = make(map[libcommon.Hash][]byte)
+ tsw.tds.currentBuffer.storageUpdates[addrHash] = m
+ }
+ tsw.tds.currentBuffer.storageIncarnation[addrHash] = incarnation
+ seckey, err := libcommon.HashData(key.Bytes())
+ if err != nil {
+ return err
+ }
+ var storageKey common.StorageKey
+ copy(storageKey[:], dbutils.GenerateCompositeStorageKey(addrHash, incarnation, seckey))
+
+ storagePlainKey := dbutils.GenerateStoragePlainKey(address, *key)
+ tsw.tds.currentBuffer.storageReads[storageKey] = storagePlainKey
+ if len(v) > 0 {
+ m[seckey] = v
+ } else {
+ m[seckey] = nil
+ }
+ //fmt.Printf("WriteAccountStorage %x %x: %x, buffer %d\n", addrHash, seckey, value, len(tsw.tds.buffers))
+ return nil
+}
+
+// ExtractWitness produces block witness for the block just been processed, in a serialised form
+func (tds *TrieDbState) ExtractWitness(trace bool, isBinary bool) (*trie.Witness, error) {
+ rs := tds.retainListBuilder.Build(isBinary)
+
+ return tds.makeBlockWitness(trace, rs, isBinary)
+}
+
+// ExtractWitness produces block witness for the block just been processed, in a serialised form
+func (tds *TrieDbState) ExtractWitnessForPrefix(prefix []byte, trace bool, isBinary bool) (*trie.Witness, error) {
+ rs := tds.retainListBuilder.Build(isBinary)
+
+ return tds.makeBlockWitnessForPrefix(prefix, trace, rs, isBinary)
+}
+
+func (tds *TrieDbState) makeBlockWitnessForPrefix(prefix []byte, trace bool, rl trie.RetainDecider, isBinary bool) (*trie.Witness, error) {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+
+ t := tds.t
+ // if isBinary {
+ // t = trie.HexToBin(tds.t).Trie()
+ // }
+
+ return t.ExtractWitnessForPrefix(prefix, trace, rl)
+}
+
+func (tds *TrieDbState) makeBlockWitness(trace bool, rl trie.RetainDecider, isBinary bool) (*trie.Witness, error) {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+
+ t := tds.t
+ // if isBinary {
+ // t = trie.HexToBin(tds.t).Trie()
+ // }
+
+ return t.ExtractWitness(trace, rl)
+}
+
+func (tsw *TrieStateWriter) CreateContract(address libcommon.Address) error {
+ addrHash := libcommon.Hash(crypto.Keccak256(address.Bytes()))
+ tsw.tds.currentBuffer.created[addrHash] = address
+ tsw.tds.currentBuffer.accountReads[addrHash] = address
+ delete(tsw.tds.currentBuffer.storageUpdates, addrHash)
+ delete(tsw.tds.currentBuffer.storageIncarnation, addrHash)
+ return nil
+}
+
+func (tds *TrieDbState) getBlockNr() uint64 {
+ return atomic.LoadUint64(&tds.blockNr)
+}
+
+func (tds *TrieDbState) setBlockNr(n uint64) {
+ atomic.StoreUint64(&tds.blockNr, n)
+}
+
+func (tds *TrieDbState) GetTrieHash() libcommon.Hash {
+ tds.tMu.Lock()
+ defer tds.tMu.Unlock()
+ return tds.t.Hash()
+}
diff --git a/core/state/txtask.go b/core/state/txtask.go
index 8604c3a38d4..15551bd6a38 100644
--- a/core/state/txtask.go
+++ b/core/state/txtask.go
@@ -19,6 +19,8 @@ package state
import (
"container/heap"
"context"
+ "fmt"
+ "github.com/erigontech/erigon-lib/common/dbg"
"sync"
"time"
@@ -106,6 +108,10 @@ func (t *TxTask) CreateReceipt(tx kv.Tx) {
}
cumulativeGasUsed += t.UsedGas
+ if t.UsedGas == 0 {
+ msg := fmt.Sprintf("no gas used stack: %s tx %+v", dbg.Stack(), t.Tx)
+ panic(msg)
+ }
r := t.createReceipt(cumulativeGasUsed)
r.FirstLogIndexWithinBlock = firstLogIndex
@@ -140,7 +146,7 @@ func (t *TxTask) createReceipt(cumulativeGasUsed uint64) *types.Receipt {
//}
return receipt
}
-func (t *TxTask) Reset() {
+func (t *TxTask) Reset() *TxTask {
t.BalanceIncreaseSet = nil
returnReadList(t.ReadLists)
t.ReadLists = nil
@@ -149,6 +155,9 @@ func (t *TxTask) Reset() {
t.Logs = nil
t.TraceFroms = nil
t.TraceTos = nil
+ t.Error = nil
+ t.Failed = false
+ return t
}
// TxTaskQueue non-thread-safe priority-queue
diff --git a/core/state_transition.go b/core/state_transition.go
index fdda38bd87c..52141f37dbe 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -62,6 +62,9 @@ The state transitioning model does all the necessary work to work out a valid ne
5) Run Script section
6) Derive new state root
*/
+
+var ErrStateTransitionFailed = errors.New("state transitaion failed")
+
type StateTransition struct {
gp *GasPool
msg Message
@@ -209,7 +212,11 @@ func (st *StateTransition) buyGas(gasBailout bool) error {
}
}
}
- if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
+ balance, err := st.state.GetBalance(st.msg.From())
+ if err != nil {
+ return err
+ }
+ if have, want := balance, balanceCheck; have.Cmp(want) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
}
st.state.SubBalance(st.msg.From(), gasVal, tracing.BalanceDecreaseGasBuy)
@@ -241,7 +248,10 @@ func CheckEip1559TxGasFeeCap(from libcommon.Address, gasFeeCap, tip, baseFee *ui
func (st *StateTransition) preCheck(gasBailout bool) error {
// Make sure this transaction's nonce is correct.
if st.msg.CheckNonce() {
- stNonce := st.state.GetNonce(st.msg.From())
+ stNonce, err := st.state.GetNonce(st.msg.From())
+ if err != nil {
+ return fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
if msgNonce := st.msg.Nonce(); stNonce < msgNonce {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
st.msg.From().Hex(), msgNonce, stNonce)
@@ -254,13 +264,21 @@ func (st *StateTransition) preCheck(gasBailout bool) error {
}
// Make sure the sender is an EOA (EIP-3607)
- if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) {
+ codeHash, err := st.state.GetCodeHash(st.msg.From())
+ if err != nil {
+ return fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ if codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) {
// libcommon.Hash{} means that the sender is not in the state.
// Historically there were transactions with 0 gas price and non-existing sender,
// so we have to allow that.
// eip-7702 allows tx origination from accounts having delegated designation code.
- if _, ok := st.state.GetDelegatedDesignation(st.msg.From()); !ok {
+ _, ok, err := st.state.GetDelegatedDesignation(st.msg.From())
+ if err != nil {
+ return fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ if !ok {
return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
st.msg.From().Hex(), codeHash)
}
@@ -307,8 +325,16 @@ func (st *StateTransition) preCheck(gasBailout bool) error {
// nil evm execution result.
func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtypes.ExecutionResult, error) {
coinbase := st.evm.Context.Coinbase
- senderInitBalance := st.state.GetBalance(st.msg.From()).Clone()
- coinbaseInitBalance := st.state.GetBalance(coinbase).Clone()
+ senderInitBalance, err := st.state.GetBalance(st.msg.From())
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ senderInitBalance = senderInitBalance.Clone()
+ coinbaseInitBalance, err := st.state.GetBalance(coinbase)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ coinbaseInitBalance = coinbaseInitBalance.Clone()
// First check this message satisfies all consensus rules before
// applying the message. The rules include these clauses
@@ -341,7 +367,11 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
if !contractCreation {
// Increment the nonce for the next transaction
- st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
+ nonce, err := st.state.GetNonce(sender.Address())
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ st.state.SetNonce(msg.From(), nonce+1)
}
// set code tx
@@ -375,37 +405,57 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
// authority is added to accessed_address in prepare step
// 4. authority code should be empty or already delegated
- if codeHash := st.state.GetCodeHash(authority); codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) {
+ codeHash, err := st.state.GetCodeHash(authority)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ if codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) {
// check for delegation
- if _, ok := st.state.GetDelegatedDesignation(authority); ok {
- // noop: has delegated designation
- } else {
+ _, ok, err := st.state.GetDelegatedDesignation(authority)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ if !ok {
log.Debug("authority code is not empty or not delegated, skipping", "auth index", i)
continue
}
+ // noop: has delegated designation
}
// 5. nonce check
- authorityNonce := st.state.GetNonce(authority)
+ authorityNonce, err := st.state.GetNonce(authority)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
if authorityNonce != auth.Nonce {
log.Debug("invalid nonce, skipping", "auth index", i)
continue
}
// 6. Add PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST gas to the global refund counter if authority exists in the trie.
- if st.state.Exist(authority) {
+ exists, err := st.state.Exist(authority)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ if exists {
st.state.AddRefund(fixedgas.PerEmptyAccountCost - fixedgas.PerAuthBaseCost)
}
// 7. set authority code
if auth.Address == (libcommon.Address{}) {
- st.state.SetCode(authority, nil)
+ if err := st.state.SetCode(authority, nil); err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
} else {
- st.state.SetCode(authority, types.AddressToDelegation(auth.Address))
+ if err := st.state.SetCode(authority, types.AddressToDelegation(auth.Address)); err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
}
// 8. increase the nonce of authority
- st.state.SetNonce(authority, authorityNonce+1)
+ if err := st.state.SetNonce(authority, authorityNonce+1); err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
}
}
@@ -422,7 +472,11 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
var bailout bool
// Gas bailout (for trace_call) should only be applied if there is not sufficient balance to perform value transfer
if gasBailout {
- if !msg.Value().IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) {
+ canTransfer, err := st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value())
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
+ if !msg.Value().IsZero() && !canTransfer {
bailout = true
}
}
@@ -435,8 +489,9 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
// Execute the preparatory steps for state transition which includes:
// - prepare accessList(post-berlin; eip-7702)
// - reset transient storage(eip 1153)
- st.state.Prepare(rules, msg.From(), coinbase, msg.To(), vm.ActivePrecompiles(rules), accessTuples, verifiedAuthorities)
-
+ if err = st.state.Prepare(rules, msg.From(), coinbase, msg.To(), vm.ActivePrecompiles(rules), accessTuples, verifiedAuthorities); err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
var (
ret []byte
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
@@ -469,7 +524,9 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
}
amount := new(uint256.Int).SetUint64(st.gasUsed())
amount.Mul(amount, effectiveTip) // gasUsed * effectiveTip = how much goes to the block producer (miner, validator)
- st.state.AddBalance(coinbase, amount, tracing.BalanceIncreaseRewardTransactionFee)
+ if err := st.state.AddBalance(coinbase, amount, tracing.BalanceIncreaseRewardTransactionFee); err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err)
+ }
if !msg.IsFree() && rules.IsLondon {
burntContractAddress := st.evm.ChainConfig().GetBurntContract(st.evm.Context.BlockNumber)
if burntContractAddress != nil {
diff --git a/core/types/gen_genesis.go b/core/types/gen_genesis.go
index d6ff602976e..3e3dba283e0 100644
--- a/core/types/gen_genesis.go
+++ b/core/types/gen_genesis.go
@@ -11,7 +11,6 @@ import (
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/hexutility"
"github.com/erigontech/erigon-lib/common/math"
- common0 "github.com/erigontech/erigon-lib/common"
)
var _ = (*genesisSpecMarshaling)(nil)
@@ -19,24 +18,24 @@ var _ = (*genesisSpecMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (g Genesis) MarshalJSON() ([]byte, error) {
type Genesis struct {
- Config *chain.Config `json:"config"`
- Nonce math.HexOrDecimal64 `json:"nonce"`
- Timestamp math.HexOrDecimal64 `json:"timestamp"`
- ExtraData hexutility.Bytes `json:"extraData"`
- GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
- Mixhash common.Hash `json:"mixHash"`
- Coinbase common.Address `json:"coinbase"`
- Alloc map[common0.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
- AuRaSeal *AuRaSeal `json:"seal"`
- Number math.HexOrDecimal64 `json:"number"`
- GasUsed math.HexOrDecimal64 `json:"gasUsed"`
- ParentHash common.Hash `json:"parentHash"`
- BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
- BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"`
- ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"`
- ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
- RequestsHash *common.Hash `json:"requestsHash"`
+ Config *chain.Config `json:"config"`
+ Nonce math.HexOrDecimal64 `json:"nonce"`
+ Timestamp math.HexOrDecimal64 `json:"timestamp"`
+ ExtraData hexutility.Bytes `json:"extraData"`
+ GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
+ Mixhash common.Hash `json:"mixHash"`
+ Coinbase common.Address `json:"coinbase"`
+ Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
+ AuRaSeal *AuRaSeal `json:"seal"`
+ Number math.HexOrDecimal64 `json:"number"`
+ GasUsed math.HexOrDecimal64 `json:"gasUsed"`
+ ParentHash common.Hash `json:"parentHash"`
+ BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
+ BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"`
+ ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"`
+ ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
+ RequestsHash *common.Hash `json:"requestsHash"`
}
var enc Genesis
enc.Config = g.Config
@@ -48,9 +47,9 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
enc.Mixhash = g.Mixhash
enc.Coinbase = g.Coinbase
if g.Alloc != nil {
- enc.Alloc = make(map[common0.UnprefixedAddress]GenesisAccount, len(g.Alloc))
+ enc.Alloc = make(map[common.UnprefixedAddress]GenesisAccount, len(g.Alloc))
for k, v := range g.Alloc {
- enc.Alloc[common0.UnprefixedAddress(k)] = v
+ enc.Alloc[common.UnprefixedAddress(k)] = v
}
}
enc.AuRaSeal = g.AuRaSeal
@@ -68,24 +67,24 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
// UnmarshalJSON unmarshals from JSON.
func (g *Genesis) UnmarshalJSON(input []byte) error {
type Genesis struct {
- Config *chain.Config `json:"config"`
- Nonce *math.HexOrDecimal64 `json:"nonce"`
- Timestamp *math.HexOrDecimal64 `json:"timestamp"`
- ExtraData *hexutility.Bytes `json:"extraData"`
- GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
- Mixhash *common.Hash `json:"mixHash"`
- Coinbase *common.Address `json:"coinbase"`
- Alloc map[common0.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
- AuRaSeal *AuRaSeal `json:"seal"`
- Number *math.HexOrDecimal64 `json:"number"`
- GasUsed *math.HexOrDecimal64 `json:"gasUsed"`
- ParentHash *common.Hash `json:"parentHash"`
- BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
- BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"`
- ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"`
- ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
- RequestsHash *common.Hash `json:"requestsHash"`
+ Config *chain.Config `json:"config"`
+ Nonce *math.HexOrDecimal64 `json:"nonce"`
+ Timestamp *math.HexOrDecimal64 `json:"timestamp"`
+ ExtraData *hexutility.Bytes `json:"extraData"`
+ GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
+ Mixhash *common.Hash `json:"mixHash"`
+ Coinbase *common.Address `json:"coinbase"`
+ Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
+ AuRaSeal *AuRaSeal `json:"seal"`
+ Number *math.HexOrDecimal64 `json:"number"`
+ GasUsed *math.HexOrDecimal64 `json:"gasUsed"`
+ ParentHash *common.Hash `json:"parentHash"`
+ BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
+ BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"`
+ ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"`
+ ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
+ RequestsHash *common.Hash `json:"requestsHash"`
}
var dec Genesis
if err := json.Unmarshal(input, &dec); err != nil {
diff --git a/core/vm/eips.go b/core/vm/eips.go
index e2d17673e21..0625ba8a8d5 100644
--- a/core/vm/eips.go
+++ b/core/vm/eips.go
@@ -95,7 +95,10 @@ func enable1884(jt *JumpTable) {
}
func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) {
- balance := interpreter.evm.IntraBlockState().GetBalance(callContext.Contract.Address())
+ balance, err := interpreter.evm.IntraBlockState().GetBalance(callContext.Contract.Address())
+ if err != nil {
+ return nil, err
+ }
callContext.Stack.Push(balance)
return nil, nil
}
diff --git a/core/vm/errors.go b/core/vm/errors.go
index ce8ff51f1eb..b8fbee9adc8 100644
--- a/core/vm/errors.go
+++ b/core/vm/errors.go
@@ -49,6 +49,10 @@ var (
// errStopToken is an internal token indicating interpreter loop termination,
// never returned to outside callers.
errStopToken = errors.New("stop token")
+ //
+ // ErrIntraBlockStateFailed indicates a fatal error when processing IBS
+ // requests
+ ErrIntraBlockStateFailed = errors.New("ibs fatal error")
)
// ErrStackUnderflow wraps an evm error when the items on the stack less
diff --git a/core/vm/evm.go b/core/vm/evm.go
index a01a97d8a2a..4b85d8c70f1 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -20,6 +20,7 @@
package vm
import (
+ "fmt"
"sync/atomic"
"github.com/holiman/uint256"
@@ -189,7 +190,11 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp
}
if typ == CALL || typ == CALLCODE {
// Fail if we're trying to transfer more than the available balance
- if !value.IsZero() && !evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) {
+ canTransfer, err := evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value)
+ if err != nil {
+ return nil, 0, err
+ }
+ if !value.IsZero() && !canTransfer {
if !bailout {
return nil, gas, ErrInsufficientBalance
}
@@ -198,13 +203,20 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp
p, isPrecompile := evm.precompile(addr)
var code []byte
if !isPrecompile {
- code = evm.intraBlockState.ResolveCode(addr)
+ code, err = evm.intraBlockState.ResolveCode(addr)
+ if err != nil {
+ return nil, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
}
snapshot := evm.intraBlockState.Snapshot()
if typ == CALL {
- if !evm.intraBlockState.Exist(addr) {
+ exist, err := evm.intraBlockState.Exist(addr)
+ if err != nil {
+ return nil, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
+ if !exist {
if !isPrecompile && evm.chainRules.IsSpuriousDragon && value.IsZero() {
if evm.config.Debug {
v := value
@@ -270,7 +282,11 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp
addrCopy := addr
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
- codeHash := evm.intraBlockState.ResolveCodeHash(addrCopy)
+ var codeHash libcommon.Hash
+ codeHash, err = evm.intraBlockState.ResolveCodeHash(addrCopy)
+ if err != nil {
+ return nil, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
var contract *Contract
if typ == CALLCODE {
contract = NewContract(caller, caller.Address(), value, gas, evm.config.SkipAnalysis, evm.JumpDestCache)
@@ -385,14 +401,21 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemainin
err = ErrDepth
return nil, libcommon.Address{}, gasRemaining, err
}
- if !evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) {
+ canTransfer, err := evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value)
+ if err != nil {
+ return nil, libcommon.Address{}, 0, err
+ }
+ if !canTransfer {
if !bailout {
err = ErrInsufficientBalance
return nil, libcommon.Address{}, gasRemaining, err
}
}
if incrementNonce {
- nonce := evm.intraBlockState.GetNonce(caller.Address())
+ nonce, err := evm.intraBlockState.GetNonce(caller.Address())
+ if err != nil {
+ return nil, libcommon.Address{}, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
if nonce+1 < nonce {
err = ErrNonceUintOverflow
return nil, libcommon.Address{}, gasRemaining, err
@@ -405,8 +428,15 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemainin
evm.intraBlockState.AddAddressToAccessList(address)
}
// Ensure there's no existing contract already at the designated address
- contractHash := evm.intraBlockState.ResolveCodeHash(address)
- if evm.intraBlockState.GetNonce(address) != 0 || (contractHash != (libcommon.Hash{}) && contractHash != trie.EmptyCodeHash) {
+ contractHash, err := evm.intraBlockState.ResolveCodeHash(address)
+ if err != nil {
+ return nil, libcommon.Address{}, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
+ nonce, err := evm.intraBlockState.GetNonce(address)
+ if err != nil {
+ return nil, libcommon.Address{}, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
+ if nonce != 0 || (contractHash != (libcommon.Hash{}) && contractHash != trie.EmptyCodeHash) {
err = ErrContractAddressCollision
return nil, libcommon.Address{}, 0, err
}
@@ -481,7 +511,11 @@ func (evm *EVM) maxCodeSize() int {
// Create creates a new contract using code as deployment code.
// DESCRIBED: docs/programmers_guide/guide.md#nonce
func (evm *EVM) Create(caller ContractRef, code []byte, gasRemaining uint64, endowment *uint256.Int, bailout bool) (ret []byte, contractAddr libcommon.Address, leftOverGas uint64, err error) {
- contractAddr = crypto.CreateAddress(caller.Address(), evm.intraBlockState.GetNonce(caller.Address()))
+ nonce, err := evm.intraBlockState.GetNonce(caller.Address())
+ if err != nil {
+ return nil, libcommon.Address{}, 0, err
+ }
+ contractAddr = crypto.CreateAddress(caller.Address(), nonce)
return evm.create(caller, &codeAndHash{code: code}, gasRemaining, endowment, contractAddr, CREATE, true /* incrementNonce */, bailout)
}
diff --git a/core/vm/evmtypes/evmtypes.go b/core/vm/evmtypes/evmtypes.go
index 775c4600acd..8e1e46fd271 100644
--- a/core/vm/evmtypes/evmtypes.go
+++ b/core/vm/evmtypes/evmtypes.go
@@ -103,10 +103,10 @@ func (result *ExecutionResult) Revert() []byte {
type (
// CanTransferFunc is the signature of a transfer guard function
- CanTransferFunc func(IntraBlockState, common.Address, *uint256.Int) bool
+ CanTransferFunc func(IntraBlockState, common.Address, *uint256.Int) (bool, error)
// TransferFunc is the signature of a transfer function
- TransferFunc func(IntraBlockState, common.Address, common.Address, *uint256.Int, bool)
+ TransferFunc func(IntraBlockState, common.Address, common.Address, *uint256.Int, bool) error
// GetHashFunc returns the nth block hash in the blockchain
// and is used by the BLOCKHASH EVM op code.
@@ -119,50 +119,50 @@ type (
// IntraBlockState is an EVM database for full state querying.
type IntraBlockState interface {
- CreateAccount(common.Address, bool)
+ CreateAccount(common.Address, bool) error
- SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)
- AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)
- GetBalance(common.Address) *uint256.Int
+ SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) error
+ AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) error
+ GetBalance(common.Address) (*uint256.Int, error)
- GetNonce(common.Address) uint64
- SetNonce(common.Address, uint64)
+ GetNonce(common.Address) (uint64, error)
+ SetNonce(common.Address, uint64) error
- GetCodeHash(common.Address) common.Hash
- GetCode(common.Address) []byte
- SetCode(common.Address, []byte)
- GetCodeSize(common.Address) int
+ GetCodeHash(common.Address) (common.Hash, error)
+ GetCode(common.Address) ([]byte, error)
+ SetCode(common.Address, []byte) error
+ GetCodeSize(common.Address) (int, error)
// eip-7702; delegated designations
- ResolveCodeHash(common.Address) common.Hash
- ResolveCode(common.Address) []byte
- ResolveCodeSize(common.Address) int
- GetDelegatedDesignation(common.Address) (common.Address, bool)
+ ResolveCodeHash(common.Address) (common.Hash, error)
+ ResolveCode(common.Address) ([]byte, error)
+ ResolveCodeSize(common.Address) (int, error)
+ GetDelegatedDesignation(common.Address) (common.Address, bool, error)
AddRefund(uint64)
SubRefund(uint64)
GetRefund() uint64
- GetCommittedState(common.Address, *common.Hash, *uint256.Int)
- GetState(address common.Address, slot *common.Hash, outValue *uint256.Int)
- SetState(common.Address, *common.Hash, uint256.Int)
+ GetCommittedState(common.Address, *common.Hash, *uint256.Int) error
+ GetState(address common.Address, slot *common.Hash, outValue *uint256.Int) error
+ SetState(common.Address, *common.Hash, uint256.Int) error
GetTransientState(addr common.Address, key common.Hash) uint256.Int
SetTransientState(addr common.Address, key common.Hash, value uint256.Int)
- Selfdestruct(common.Address) bool
- HasSelfdestructed(common.Address) bool
- Selfdestruct6780(common.Address)
+ Selfdestruct(common.Address) (bool, error)
+ HasSelfdestructed(common.Address) (bool, error)
+ Selfdestruct6780(common.Address) error
// Exist reports whether the given account exists in state.
// Notably this should also return true for suicided accounts.
- Exist(common.Address) bool
+ Exist(common.Address) (bool, error)
// Empty returns whether the given account is empty. Empty
// is defined according to EIP161 (balance = nonce = code = 0).
- Empty(common.Address) bool
+ Empty(common.Address) (bool, error)
Prepare(rules *chain.Rules, sender, coinbase common.Address, dest *common.Address,
- precompiles []common.Address, txAccesses types.AccessList, authorities []common.Address)
+ precompiles []common.Address, txAccesses types.AccessList, authorities []common.Address) error
AddressInAccessList(addr common.Address) bool
// AddAddressToAccessList adds the given address to the access list. This operation is safe to perform
diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index ef38856ccfc..7d98f49529c 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -391,11 +391,21 @@ func gasCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memo
address = libcommon.Address(stack.Back(1).Bytes20())
)
if evm.ChainRules().IsSpuriousDragon {
- if transfersValue && evm.IntraBlockState().Empty(address) {
+ empty, err := evm.IntraBlockState().Empty(address)
+ if err != nil {
+ return 0, err
+ }
+ if transfersValue && empty {
+ gas += params.CallNewAccountGas
+ }
+ } else {
+ exists, err := evm.IntraBlockState().Exist(address)
+ if err != nil {
+ return 0, err
+ }
+ if !exists {
gas += params.CallNewAccountGas
}
- } else if !evm.IntraBlockState().Exist(address) {
- gas += params.CallNewAccountGas
}
if transfersValue {
gas += params.CallValueTransferGas
@@ -499,15 +509,33 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memo
if evm.ChainRules().IsSpuriousDragon {
// if empty and transfers value
- if evm.IntraBlockState().Empty(address) && !evm.IntraBlockState().GetBalance(contract.Address()).IsZero() {
+ empty, err := evm.IntraBlockState().Empty(address)
+ if err != nil {
+ return 0, err
+ }
+ balance, err := evm.IntraBlockState().GetBalance(contract.Address())
+ if err != nil {
+ return 0, err
+ }
+ if empty && !balance.IsZero() {
+ gas += params.CreateBySelfdestructGas
+ }
+ } else {
+ exist, err := evm.IntraBlockState().Exist(address)
+ if err != nil {
+ return 0, err
+ }
+ if !exist {
gas += params.CreateBySelfdestructGas
}
- } else if !evm.IntraBlockState().Exist(address) {
- gas += params.CreateBySelfdestructGas
}
}
- if !evm.IntraBlockState().HasSelfdestructed(contract.Address()) {
+ hasSelfdestructed, err := evm.IntraBlockState().HasSelfdestructed(contract.Address())
+ if err != nil {
+ return 0, err
+ }
+ if !hasSelfdestructed {
evm.IntraBlockState().AddRefund(params.SelfdestructRefundGas)
}
return gas, nil
diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go
index 4703b81f87f..fc33308a2eb 100644
--- a/core/vm/gas_table_test.go
+++ b/core/vm/gas_table_test.go
@@ -144,8 +144,10 @@ func TestEIP2200(t *testing.T) {
_ = s.CommitBlock(params.AllProtocolChanges.Rules(0, 0), w)
vmctx := evmtypes.BlockContext{
- CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) bool { return true },
- Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) {},
+ CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) (bool, error) { return true, nil },
+ Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) error {
+ return nil
+ },
}
vmenv := vm.NewEVM(vmctx, evmtypes.TxContext{}, s, params.AllProtocolChanges, vm.Config{ExtraEips: []int{2200}})
@@ -207,8 +209,10 @@ func TestCreateGas(t *testing.T) {
_ = s.CommitBlock(params.TestChainConfig.Rules(0, 0), stateWriter)
vmctx := evmtypes.BlockContext{
- CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) bool { return true },
- Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) {},
+ CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) (bool, error) { return true, nil },
+ Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) error {
+ return nil
+ },
}
config := vm.Config{}
if tt.eip3860 {
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 1cd62cfa7ee..e0b602323ff 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -287,7 +287,11 @@ func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.Peek()
address := libcommon.Address(slot.Bytes20())
- slot.Set(interpreter.evm.IntraBlockState().GetBalance(address))
+ balance, err := interpreter.evm.IntraBlockState().GetBalance(address)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
+ slot.Set(balance)
return nil, nil
}
@@ -371,7 +375,11 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.Peek()
- slot.SetUint64(uint64(interpreter.evm.IntraBlockState().ResolveCodeSize(slot.Bytes20())))
+ codeSize, err := interpreter.evm.IntraBlockState().ResolveCodeSize(slot.Bytes20())
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
+ slot.SetUint64(uint64(codeSize))
return nil, nil
}
@@ -408,7 +416,11 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
addr := libcommon.Address(a.Bytes20())
len64 := length.Uint64()
- codeCopy := getDataBig(interpreter.evm.IntraBlockState().ResolveCode(addr), &codeOffset, len64)
+ code, err := interpreter.evm.IntraBlockState().ResolveCode(addr)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err)
+ }
+ codeCopy := getDataBig(code, &codeOffset, len64)
scope.Memory.Set(memOffset.Uint64(), len64, codeCopy)
return nil, nil
}
@@ -454,10 +466,18 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
slot := scope.Stack.Peek()
address := libcommon.Address(slot.Bytes20())
- if interpreter.evm.IntraBlockState().Empty(address) {
+ empty, err := interpreter.evm.IntraBlockState().Empty(address)
+ if err != nil {
+ return nil, err
+ }
+ if empty {
slot.Clear()
} else {
- slot.SetBytes(interpreter.evm.IntraBlockState().ResolveCodeHash(address).Bytes())
+ codeHash, err := interpreter.evm.IntraBlockState().ResolveCodeHash(address)
+ if err != nil {
+ return nil, err
+ }
+ slot.SetBytes(codeHash.Bytes())
}
return nil, nil
}
@@ -559,8 +579,7 @@ func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
loc := scope.Stack.Peek()
interpreter.hasherBuf = loc.Bytes32()
- interpreter.evm.IntraBlockState().GetState(scope.Contract.Address(), &interpreter.hasherBuf, loc)
- return nil, nil
+ return nil, interpreter.evm.IntraBlockState().GetState(scope.Contract.Address(), &interpreter.hasherBuf, loc)
}
func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
@@ -570,8 +589,7 @@ func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
loc := scope.Stack.Pop()
val := scope.Stack.Pop()
interpreter.hasherBuf = loc.Bytes32()
- interpreter.evm.IntraBlockState().SetState(scope.Contract.Address(), &interpreter.hasherBuf, val)
- return nil, nil
+ return nil, interpreter.evm.IntraBlockState().SetState(scope.Contract.Address(), &interpreter.hasherBuf, val)
}
func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
@@ -879,7 +897,10 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
beneficiary := scope.Stack.Pop()
callerAddr := scope.Contract.Address()
beneficiaryAddr := libcommon.Address(beneficiary.Bytes20())
- balance := interpreter.evm.IntraBlockState().GetBalance(callerAddr)
+ balance, err := interpreter.evm.IntraBlockState().GetBalance(callerAddr)
+ if err != nil {
+ return nil, err
+ }
if interpreter.evm.Config().Debug {
if interpreter.cfg.Debug {
interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, callerAddr, beneficiaryAddr, false /* precompile */, false /* create */, []byte{}, 0, balance, nil /* code */)
@@ -898,7 +919,11 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon
beneficiary := scope.Stack.Pop()
callerAddr := scope.Contract.Address()
beneficiaryAddr := libcommon.Address(beneficiary.Bytes20())
- balance := *interpreter.evm.IntraBlockState().GetBalance(callerAddr)
+ pbalance, err := interpreter.evm.IntraBlockState().GetBalance(callerAddr)
+ if err != nil {
+ return nil, err
+ }
+ balance := *pbalance
interpreter.evm.IntraBlockState().SubBalance(callerAddr, &balance, tracing.BalanceDecreaseSelfdestruct)
interpreter.evm.IntraBlockState().AddBalance(beneficiaryAddr, &balance, tracing.BalanceIncreaseSelfdestruct)
interpreter.evm.IntraBlockState().Selfdestruct6780(callerAddr)
diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go
index a8c3fec9b33..fe1817e8013 100644
--- a/core/vm/operations_acl.go
+++ b/core/vm/operations_acl.go
@@ -231,10 +231,22 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
gas = params.ColdAccountAccessCostEIP2929
}
// if empty and transfers value
- if evm.IntraBlockState().Empty(address) && !evm.IntraBlockState().GetBalance(contract.Address()).IsZero() {
+ empty, err := evm.IntraBlockState().Empty(address)
+ if err != nil {
+ return 0, err
+ }
+ balance, err := evm.IntraBlockState().GetBalance(contract.Address())
+ if err != nil {
+ return 0, err
+ }
+ if empty && !balance.IsZero() {
gas += params.CreateBySelfdestructGas
}
- if refundsEnabled && !evm.IntraBlockState().HasSelfdestructed(contract.Address()) {
+ hasSelfdestructed, err := evm.IntraBlockState().HasSelfdestructed(contract.Address())
+ if err != nil {
+ return 0, err
+ }
+ if refundsEnabled && !hasSelfdestructed {
evm.IntraBlockState().AddRefund(params.SelfdestructRefundGas)
}
return gas, nil
@@ -266,7 +278,11 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
}
// Check if code is a delegation and if so, charge for resolution.
- if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
+ dd, ok, err := evm.intraBlockState.GetDelegatedDesignation(addr)
+ if err != nil {
+ return 0, err
+ }
+ if ok {
var ddCost uint64
if evm.intraBlockState.AddAddressToAccessList(dd) {
ddCost = params.ColdAccountAccessCostEIP2929
@@ -311,8 +327,11 @@ func gasEip7702CodeCheck(evm *EVM, contract *Contract, stack *stack.Stack, mem *
// Check if code is a delegation and if so, charge for resolution
cost = params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929
}
-
- if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
+ dd, ok, err := evm.intraBlockState.GetDelegatedDesignation(addr)
+ if err != nil {
+ return 0, err
+ }
+ if ok {
if evm.intraBlockState.AddAddressToAccessList(dd) {
cost += params.ColdAccountAccessCostEIP2929
} else {
@@ -340,7 +359,11 @@ func gasExtCodeCopyEIP7702(evm *EVM, contract *Contract, stack *stack.Stack, mem
}
// Check if addr has a delegation and if so, charge for resolution
- if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
+ dd, ok, err := evm.intraBlockState.GetDelegatedDesignation(addr)
+ if err != nil {
+ return 0, err
+ }
+ if ok {
var overflow bool
if evm.intraBlockState.AddAddressToAccessList(dd) {
if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929); overflow {
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index 5515933f389..77748306170 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -244,7 +244,10 @@ func Call(address libcommon.Address, input []byte, cfg *Config) ([]byte, uint64,
vmenv := NewEnv(cfg)
- sender := cfg.State.GetOrNewStateObject(cfg.Origin)
+ sender, err := cfg.State.GetOrNewStateObject(cfg.Origin)
+ if err != nil {
+ return nil, 0, err
+ }
statedb := cfg.State
rules := vmenv.ChainRules()
statedb.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil, nil)
diff --git a/docs/DEV_CHAIN.md b/docs/DEV_CHAIN.md
index ad3ec3ebc68..57c7db3ee8c 100644
--- a/docs/DEV_CHAIN.md
+++ b/docs/DEV_CHAIN.md
@@ -33,7 +33,7 @@ Or, you could start the rpcdaemon internally together
Argument notes:
* datadir : Tells where the data is stored, default level is dev folder.
* chain : Tells that we want to run Erigon in the dev chain.
- * private.api.addr=localhost:9090 : Tells where Eigon is going to listen for connections.
+ * private.api.addr=localhost:9090 : Tells where Erigon is going to listen for connections.
* mine : Add this if you want the node to mine.
* dev.period : Add this to specify the timing interval among blocks. Number of seconds MUST be > 0 (if you want empty blocks) otherwise the default value 0 does not allow mining of empty blocks.
* http.api: List of services to start on http (rpc) access
@@ -150,7 +150,7 @@ From the RPC daemon terminal, you will see something like this
Now we want to check the creation of a new block and that all the nodes sync.
-Below we can see that block 1 is created (blocn_num=1) and that the next block to be proposed increments from 1 to 2 ( block=2). The other nodes will see the same update.
+Below we can see that block 1 is created (block_num=1) and that the next block to be proposed increments from 1 to 2 ( block=2). The other nodes will see the same update.
diff --git a/docs/programmers_guide/witness_formal_spec.md b/docs/programmers_guide/witness_formal_spec.md
new file mode 100644
index 00000000000..bcd8346bb3d
--- /dev/null
+++ b/docs/programmers_guide/witness_formal_spec.md
@@ -0,0 +1,598 @@
+# Block Witness Formal Specification
+
+The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119).
+
+## Data Types
+
+### Basic
+
+`nil` - an empty value.
+
+`Any` - any data type. MUST NOT be `nil`.
+
+`Int` - an integer value. We treat the domain of integers as infinite,
+the overflow behaviour or mapping to the actual data types is undefined
+in this spec and should be up to implementation.
+
+`Byte` - a single byte.
+
+`Hash` - 32 byte value, representing a result of Keccak256 hashing.
+
+### Composite
+
+`()` - an empty array of arbitrary type.
+
+`(Type...)` - an array of a type `Type`. MUST NOT be empty.
+
+`{field:Type}` - an object with a field `field` of type `Type`.
+
+ - full notation: `type T = {field:Type}`
+
+ - inline `type TBase = T1{field:Type}|T2{field2:Type2}`
+
+### Type Definitions
+
+The type definitions are a bit similar to [Haskell](https://en.wikibooks.org/wiki/Haskell/Type_declarations).
+The key differences are how the arrays and type fields are defined.
+
+### Nodes
+
+```
+type Node = HashNode{raw_hash:Hash}
+ | ValueNode{raw_value:(Byte...)}
+ | AccountNode{nonce:Int balance:Int storage:nil|Node code:nil|CodeNode|HashNode}
+ | LeafNode{key:(Byte...) value:ValueNode|AccountNode}
+ | ExtensionNode{key:(Byte...) child:Node}
+ | BranchNode{child0:nil|Node child1:nil|Node child3:nil|Node ... child15:nil|Node}
+ | CodeNode{code:(Byte... )}
+```
+
+### Witness
+
+Witness MUST have at least 1 element.
+
+```
+type WitnessHeader = {version:Int}
+type Instruction = {code:Int parameter:Any...}
+type Witness = (Node|Instruction...)
+```
+
+
+## Execution Environment
+
+The witness execution environment MUST contain the following 2 elements:
+
+- **WitnessHeader** -- a header containing the version of the witness. The `version` MUST be 1.
+
+- **Witness** -- a witness to be executed;
+
+- **Substitution Rules** -- a list of all possible substitution rules.
+
+
+## Execution process
+
+Initially, the Witness MUST BE an array of `Instruction`s.
+
+Then, as substitution rules are applied to the witness, some elements of the
+array are replaced with `Node`s.
+
+The execution continues until there are no substitution rules left to execute.
+
+Here is how the execution code might look like in Go for building a single trie.
+
+```go
+witness := GetInitialWitness()
+rules := GetSubstitutionRules()
+numberOfRulesApplied := 1 // initial state
+
+for numberOfRulesApplied > 0 {
+ witness, numberOfRulesApplied := ApplyRules(witness, rules)
+}
+
+if len(witness) == 1 {
+ trie.root = witness[0]
+} else {
+ panic("witness execution failed")
+}
+
+```
+
+
+And here is an example of the execution process (we will use the set of rules
+form the **Substitution Rules** section of this document):
+
+* **Step 1**. Witness: `(HASH h1 HASH h2 BRANCH 0b101 HASH h3 BRANCH 0b11)`
+
+* **Step 2**. Apply `HASH` substitution rules.
+Witness: `(HashNode{h1} HashNode{h2} BRANCH 0b101 HashNode{h3} BRANCH 0b11)`
+
+* **Step 3**. Apply `BRANCH` substitution rules (only once, because `BRANCH 0b11`
+doesn't pass its `GUARD` statements just yet).
+Witness: `(BranchNode{0: HashNode{h1} 2:HashNode{h2}} HashNode{h3} BRANCH 0b11)`
+
+* **Step 4**. Apply `BRANCH` substitution rules again.
+Witness: `(BranchNode{0: BranchNode{0: HashNode{h1} 2:HashNode{h2}} 1:HashNode{h3}})`
+
+* **Step 5**. No more rules are applicable, the witness contains only one
+ element, the execution ends successfully.
+
+
+## End Criteria
+
+The execution ends when there are no substitution rules applicable for this
+witness.
+
+### Building a single trie from the witness
+
+If we are building a single trie from the witness, then the only SUCCESS
+execution is when the following are true:
+
+- The execution state MUST match the End Criteria
+- There MUST be only one item left in the witness
+- This item MUST be of the type `Node`
+
+In that case, this last item will be the root of the built trie.
+
+Every other end state is considered a FAILURE.
+
+
+### Building a Forest
+
+We also can build a forest of tries with this approach, by adding a new
+Instruction `NEW_TRIE` and adjusting the success criteria a bit:
+
+- The execution state MUST match the End Criteria;
+- The items that are left in the witness MUST follow this pattern: `(Node
+ NEW_TRIE ... Node)`
+- Each `Node` element will be a root of a trie.
+
+Every other end state is considered a FAILURE.
+
+
+## Instructions & Parameters
+
+A single instruction consists of substitution rules and parameters.
+
+Each instruction MAY have one or more parameters.
+The parameters values MUST be encoded in the witness.
+
+That makes it different from the helper function parameters that MAY come from the stack or MAY come from the witness.
+
+
+## Substitution rules
+
+A substitution rule consists of 3 parts:
+
+`[GUARD] PATTERN |=> RESULT`
+
+- to the left of the `|=>` sign:
+
+ - optional `GUARD` statements;
+
+ - the pattern to match against;
+
+- result, to the right of the `|=>` sign.
+
+
+### `GUARD`s
+
+Each substitution rule can have zero, one or multiple `GUARD` statements.
+Each `GUARD` statement looks like this:
+
+```
+GUARD
+```
+
+For a substitution rule to be applicable, the `` in its `GUARD` statement MUST be true.
+
+If a substitution rule has multiple `GUARD` statements, all of them MUST BE satisfied.
+
+If there are no `GUARD` statements, the substitution rule's applicability is
+only defined by the PATTERN.
+
+Example:
+```
+ GUARD NBITSET(mask) == 2
+|---- GUARD STATEMENT ---|
+
+ Node(n0) Node(n1) BRANCH(mask) |=>
+ BranchNode{MAKE_VALUES_ARRAY(mask, n0, n1)}
+```
+
+For the example rule to be applicable both facts MUST be true:
+
+1. `mask` contains only 2 bits set to 1 (the rest are set to 0);
+
+2. to the left of `BRANCH` instruction there is at least 2 `Node`s.
+
+Fact (1) comes from the `GUARD` statement.
+
+
+### PATTERN
+
+`[NodeType(boundVar1)... NodeType(boundVarN)] Instruction[(param1... paramN)]`
+
+A pattern MUST contain a single instruction.
+A pattern MAY contain one or more `Node`s to the left of the instruction to
+match.
+An instruction MAY have one or more parameters.
+
+Pattern matching is happening by the types. `Node` type means any node is
+matched, some specific node type will require a specific match.
+
+Pattern can have bound variable names for both matched nodes and instruction
+parameters (if present).
+
+Match:
+
+```
+HASH h0 HashNode{h1} HashNode{h2} BRANCH 0b11
+ |------------------- MATCH -----------|
+
+HASH h0 BranchNode{0: HashNode{h1} 1: HashNode{h2}}
+ |----------- SUBSTITUTED -------------------|
+```
+
+No match (not enough nodes to the left of the instruction):
+
+```
+HASH h0 HASH h1 HashNode{h2} BRANCH 0b11
+```
+
+### Result
+
+`NodeType(HELPER_FUNCTION(arguments))`
+
+The result is a single `Node` statement that replaces the pattern in the
+witness if it matches and the guards are passed.
+
+The result MAY contain helper functions or might have in-line computation.
+The result MUST have a specific node type. No generic `Node` is allowed.
+
+Helper functions or inline computations might use bound variables from the
+pattern.
+
+Example
+
+```
+
+Node(n0) Node(n1) BRANCH(mask) |=>
+BranchNode{MAKE_VALUES_ARRAY(mask, n0, n1)}
+ ^ ^-- ^--- BOUND NODES
+ |---- BOUND INSTRUCTION PARAM
+ |------ HELPER CALL ------------|
+|----------------- RESULT ------------------|
+
+```
+
+### Bringing it all together
+
+
+So the full syntax is this:
+
+```
+[GUARD ...] [ NodeType(bound_variable1)... ] INSTRUCTION[(param1 ...)] |=>
+Node()
+```
+
+`NodeType` is one of the types of nodes to match. Can also be `Node` to match
+any non-nil node.
+
+Substitution rules MUST be non-ambiguous. Even though, there can be multiple
+substitution rules applicable to the whole witness at the same time, there MUST
+be only one rule that is applicable to a certain position in the witness.
+
+So, the minimal substitution rule is the one for the `HASH` instruction that pushes one hash to the stack:
+```
+HASH(hashValue) |=> HashNode{hashValue}
+```
+
+
+## Helper functions
+
+Helper functions are functions that are used in GUARDs or substitution rules.
+
+Helper functions MUST be pure.
+Helper functions MUST have at least one argument.
+Helper functions MAY have variadic parameters: `HELPER_EXAMPLE(arg1, arg2, list...)`.
+Helper functions MAY contain recursion.
+
+## Instructions
+
+### `LEAF key raw_value`
+
+**Substitution rules**
+
+Replaces the instruction with a `ValueNode` wrapped with a `LeafNode`.
+
+```
+LEAF(key, raw_value) |=> LeafNode{key, ValueNode(raw_value)}
+```
+
+### `EXTENSION key`
+
+Wraps a node to the left of the instruction with an `ExtensionNode`.
+
+**Substitution rules**
+
+```
+Node(node) EXTENSION(key) |=> ExtensionNode{key, node}
+```
+
+### `HASH raw_hash`
+
+Replaces the instruction with a `HashNode`.
+
+**Substitution rules**
+
+```
+HASH(hash_value) |=> HashNode{hash_value}
+```
+
+### `CODE raw_code`
+
+Replaces the instruction with a `CodeNode`.
+
+```
+CODE(raw_code) |=> CodeNode{raw_code}
+```
+
+### `ACCOUNT_LEAF key nonce balance has_code has_storage`
+
+Replaces the instruction and, optionally, up to 2 nodes to the left of the
+instruction with a single `AccountNode` wrapped with a `LeafNode`.
+
+**Substitution rules**
+
+```
+GUARD has_code == true
+GUARD has_storage == true
+
+CodeNode(code) Node(storage_hash_node) ACCOUNT_LEAF(key, nonce, balance, has_code, has_storage) |=>
+LeafNode{key, AccountNode{nonce, balance, storage_root, code}}
+
+---
+
+GUARD has_code == true
+GUARD has_storage == true
+
+HashNode(code) Node(storage_hash_node) ACCOUNT_LEAF(key, nonce, balance, has_code, has_storage) |=>
+LeafNode{key, AccountNode{nonce, balance, storage_root, code}}
+
+---
+
+GUARD has_code == false
+GUARD has_storage == true
+
+Node(storage_root) ACCOUNT_LEAF(key, nonce, balance, has_code, has_storage) |=>
+LeafNode{key, AccountNode{nonce, balance, storage_root, nil}}
+
+---
+
+GUARD has_code == true
+GUARD has_storage == false
+
+CodeNode(code) ACCOUNT_LEAF(key, nonce, balance, has_code, has_storage) |=>
+LeafNode{key, AccountNode{nonce, balance, nil, nil, code}}
+
+---
+
+GUARD has_code == true
+GUARD has_storage == false
+
+HashNode(code) ACCOUNT_LEAF(key, nonce, balance, has_code, has_storage) |=>
+LeafNode{key, AccountNode{nonce, balance, nil, nil, code}}
+
+---
+
+GUARD has_code == false
+GUARD has_storage == false
+
+ACCOUNT_LEAF(key, nonce, balance, has_code, has_storage) |=>
+LeafNode{key, AccountNode{nonce, balance, nil, nil, nil}}
+
+```
+
+### `NEW_TRIE`
+
+No substitution rules. This instruction is used as a "divider" when building
+a forest of tries.
+
+### `BRANCH mask`
+
+Replaces `NBITSET(mask)` `Node`s to the left of the instruction with a single
+`BranchNode` with these nodes as children according to `mask`.
+
+**Substitution rules**
+```
+
+GUARD NBITSET(mask) == 2
+
+Node(n0) Node(n1) BRANCH(mask) |=>
+BranchNode{MAKE_VALUES_ARRAY(mask, n0, n1)}
+
+---
+
+GUARD NBITSET(mask) == 3
+
+Node(n0) Node(n1) Node(n2) BRANCH(mask) |=>
+BranchNode{MAKE_VALUES_ARRAY(mask, n0, n1, n2)}
+
+---
+
+...
+
+---
+
+GUARD NBITSET(mask) == 16
+
+Node(n0) Node(n1) ... Node(n15) BRANCH(mask) |=>
+BranchNode{MAKE_VALUES_ARRAY(mask, n0, n1, ..., n15)}
+```
+
+## Helper functions
+
+### `MAKE_VALUES_ARRAY`
+
+returns an array of 16 elements, where values from `values` are set to the indices where `mask` has bits set to 1. Every other place has `nil` value there.
+
+**Example**: `MAKE_VALUES_ARRAY(5, [a, b])` returns `[a, nil, b, nil, nil, ..., nil]` (binary representation of 5 is `0000000000000101`)
+
+```
+MAKE_VALUES_ARRAY(mask, values...) {
+ return MAKE_VALUES_ARRAY(mask, 0, values)
+}
+
+MAKE_VALUES_ARRAY(mask, idx, values...) {
+ if idx > 16 {
+ return []
+ }
+
+ if BIT_TEST(mask, idx) {
+ return PREPEND(FIRST(values), (MAKE_VALUES_ARRAY mask, INC(idx), REST(values)))
+ } else {
+ return PREPEND(nil, (MAKE_VALUES_ARRAY mask, INC(idx), values))
+ }
+}
+```
+
+
+### `RLP(value)`
+
+returns the RLP encoding of a value
+
+
+### `NBITSET(number)`
+
+returns number of bits set in the binary representation of `number`.
+
+### `BIT_TEST(number, n)`
+
+`n` MUST NOT be negative.
+
+returns `true` if bit `n` in `number` is set, `false` otherwise.
+
+### `PREPEND(value, array)`
+
+returns a new array with the `value` at index 0 and `array` values starting from index 1
+
+### `INC(value)`
+
+increments `value` by 1
+
+### `FIRST(array)`
+
+returns the first value in the specified array
+
+### `REST(array)`
+
+returns the array w/o the first item
+
+### `KECCAK(bytes)`
+
+returns a keccak-256 hash of `bytes`
+
+
+## Serialization
+
+The format for serialization of everything except hashes (that we know the
+length of) is [CBOR](https://cbor.io). It is RFC-specified and concise.
+
+For hashes we use the optimization of knowing the lengths, so we just read 32
+bytes
+
+### Block Witness Format
+
+Each block witness consists of a header followed by a list of instructions.
+
+There is no length of witness specified anywhere, the code expects to just reach `EOF`.
+
+Serialized Witness: `(HEADER, OP1, OP2, ..., OPn-1, OPn, EOF)`
+
+#### Encoding
+
+##### CBOR
+
+The parts of the key that are encoded with CBOR are marked by the `CBOR` function.
+
+##### Keys
+
+Keys are also using custom encryption to make them more compact.
+
+The nibbles of a key are encoded in a following way `[FLAGS NIBBLE1+NIBBLE2 NIBBLE3+NIBBLE4 NIBBLE5... ]`
+
+*FLAGS*
+* bit 0 -- 1 if the number of nibbles were odd
+* bit 1 -- 1 if the nibbles end with 0x10 (the terminator byte)
+
+This is shown later as `ENCODE_KEY` function.
+
+#### Header
+
+format: `version:byte`
+
+encoded as `[ version ]`
+
+the current version is 1.
+
+#### Instructions
+
+Each instruction starts with an opcode (`uint`).
+
+Then it might contain some data.
+
+##### `LEAF`
+
+format: `LEAF key:[]byte value:[]byte`
+
+encoded as `[ 0x00 CBOR(ENCODE_KEY(key))... CBOR(value)... ]`
+
+
+##### `EXTENSION`
+
+format: `EXTENSION key:[]byte`
+
+encoded as `[ 0x01 CBOR(ENCODE_KEY(key))... ]`
+
+
+##### `BRANCH`
+
+format: `BRANCH mask:uint32`
+
+*mask* defines which children are present
+(e.g. `0000000000001011` means that children 0, 1 and 3 are present and the other ones are not)
+
+encoded as `[ 0x02 CBOR(mask)...]`
+
+
+##### `HASH`
+
+format: `HASH hash:[32]byte`
+
+encoded as `[ 0x03 hash_byte_1 ... hash_byte_32 ]`
+
+
+##### `CODE`
+
+format: `CODE code:[]byte`
+
+encoded as `[ 0x04 CBOR(code)... ]`
+
+
+##### `ACCOUNT_LEAF`
+
+format: `ACCOUNT_LEAF key:[]byte flags [nonce:uint64] [balance:[]byte]`
+
+encoded as `[ 0x05 CBOR(ENCODE_KEY(key))... flags /CBOR(nonce).../ /CBOR(balance).../ ]`
+
+*flags* is a bitset encoded in a single bit (see [`witness_operators_test.go`](../../trie/witness_operators_test.go) to see flags in action).
+* bit 0 defines if **code** is present; if set to 1, then `has_code=true`;
+* bit 1 defines if **storage** is present; if set to 1, then `has_storage=true`;
+* bit 2 defines if **nonce** is not 0; if set to 0, *nonce* field is not encoded;
+* bit 3 defines if **balance** is not 0; if set to 0, *balance* field is not encoded;
+
+##### `NEW_TRIE`
+
+format: `NEW_TRIE`
+
+encoded as `[ 0xBB ]`
diff --git a/docs/programmers_guide/witness_format.md b/docs/programmers_guide/witness_format.md
new file mode 100644
index 00000000000..4b1508f06d9
--- /dev/null
+++ b/docs/programmers_guide/witness_format.md
@@ -0,0 +1,96 @@
+# Block Witness Format
+
+Each block witness consists of a header followed by a list of operators.
+
+There is no length of witness specified anywhere, the code expects to just reach `EOF`.
+
+Witness: `[HEADER, OP1, OP2, ..., OPn-1, OPn, EOF]`
+
+## Encoding
+
+### Keys
+
+key nibbles are encoded in a following way `[FLAGS NIBBLE1+NIBBLE2 NIBBLE3+NIBBLE4 NIBBLE5... ]`
+
+*FLAGS*
+* bit 0 -- 1 if the number of nibbles were odd
+* bit 1 -- 1 if the nibbles end with 0x10
+
+## Header
+
+format: `version:byte`
+
+encoded as `[ version ]`
+
+the current version is 1.
+
+## Operators
+
+Each operator starts with an opcode (see [`witness_operators.go`](../../trie/witness_operators.go) for exact values).
+
+Then it might contain some data.
+
+### `OpEmptyRoot`
+
+puts empty trie root to on the stack
+
+format: `OpEmptyRoot`
+
+encoded as `[ 0x06 ]`
+
+### `OpHash`
+
+puts a single hash on the stack
+
+format: `OpHash hash:[32]byte`
+
+encoded as `[ 0x03 hash_byte_1 ... hash_byte_32 ]`
+
+### `OpBranch`
+
+pops N values from the stack and adds them as the children; pushes the result to the stack; N is the number of 1's in the *mask* field.
+
+format: `OpBranch mask:uint32`
+
+*mask* defines which children are present
+(e.g. `0000000000001011` means that children 0, 1 and 3 are present and the other ones are not)
+
+encoded as `[ 0x02 CBOR(mask)...]`
+
+### `OpCode`
+
+pushes a code to the stack
+
+format: `OpCode code:[]byte`
+
+encoded as `[ 0x04 CBOR(code)... ]`
+
+### `OpExtension`
+
+pushes an extension node with a specified key on the stack
+
+format: `OpExtension key:[]byte`
+
+encoded as `[ 0x01 CBOR(key)... ]`
+
+### `OpLeaf`
+
+pushes a leaf with specified key and value to the stack
+
+format: `OpLeaf key:[]byte value:[]byte`
+
+encoded as `[ 0x00 CBOR(key)... CBOR(value)... ]`
+
+### `OpAccountLeaf`
+
+pushes a leaf with specified parameters to the stack; if flags show, before that pops 1 or 2 values from the stack;
+
+format: `OpAccountLeaf key:[]byte flags [nonce:uint64] [balance:[]byte]`
+
+encoded as `[ 0x05 CBOR(key|[]byte)... flags /CBOR(nonce).../ /CBOR(balance).../ ]`
+
+*flags* is a bitset encoded in a single bit (see [`witness_operators_test.go`](../../trie/witness_operators_test.go) to see flags in action).
+* bit 0 defines if **code** is present; if set to 1 it assumes that either `OpCode` or `OpHash` already put something on the stack;
+* bit 1 defines if **storage** is present; if set to 1, the operators preceding `OpAccountLeaf` will reconstruct a storage trie;
+* bit 2 defines if **nonce** is not 0; if set to 0, *nonce* field is not encoded;
+* bit 3 defines if **balance** is not 0; if set to 0, *balance* field is not encoded;
\ No newline at end of file
diff --git a/erigon-lib/commitment/commitment.go b/erigon-lib/commitment/commitment.go
index 60ca4bcca6f..1e60c1f790f 100644
--- a/erigon-lib/commitment/commitment.go
+++ b/erigon-lib/commitment/commitment.go
@@ -138,7 +138,7 @@ func InitializeTrieAndUpdates(tv TrieVariant, mode Mode, tmpdir string) (Trie, *
default:
trie := NewHexPatriciaHashed(length.Addr, nil, tmpdir)
- tree := NewUpdates(mode, tmpdir, trie.hashAndNibblizeKey)
+ tree := NewUpdates(mode, tmpdir, trie.HashAndNibblizeKey)
return trie, tree
}
}
diff --git a/erigon-lib/commitment/hex_patricia_hashed.go b/erigon-lib/commitment/hex_patricia_hashed.go
index 6e39f1ad034..9c6afeb22ea 100644
--- a/erigon-lib/commitment/hex_patricia_hashed.go
+++ b/erigon-lib/commitment/hex_patricia_hashed.go
@@ -35,16 +35,19 @@ import (
"github.com/erigontech/erigon-lib/etl"
"github.com/erigontech/erigon-lib/log/v3"
+ "github.com/erigontech/erigon-lib/trie"
+ "github.com/erigontech/erigon-lib/types/accounts"
+ witnesstypes "github.com/erigontech/erigon-lib/types/witness"
"github.com/erigontech/erigon-lib/common/dbg"
- "golang.org/x/crypto/sha3"
-
- "github.com/erigontech/erigon-lib/common/hexutility"
-
"github.com/erigontech/erigon-lib/common"
+ libcommon "github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon-lib/common/hexutility"
"github.com/erigontech/erigon-lib/common/length"
+ ecrypto "github.com/erigontech/erigon-lib/crypto"
rlp "github.com/erigontech/erigon-lib/rlp2"
+ "golang.org/x/crypto/sha3"
)
// keccakState wraps sha3.state. In addition to the usual hash methods, it also supports
@@ -194,27 +197,6 @@ func (cell *cell) reset() {
cell.Update.Reset()
}
-func (cell *cell) String() string {
- b := new(strings.Builder)
- b.WriteString("{")
- b.WriteString(fmt.Sprintf("loaded=%v ", cell.loaded))
- if cell.Deleted() {
- b.WriteString("DELETED ")
- }
- if cell.accountAddrLen > 0 {
- b.WriteString(fmt.Sprintf("addr=%x ", cell.accountAddr[:cell.accountAddrLen]))
- }
- if cell.storageAddrLen > 0 {
- b.WriteString(fmt.Sprintf("addr[s]=%x", cell.storageAddr[:cell.storageAddrLen]))
-
- }
- if cell.hashLen > 0 {
- b.WriteString(fmt.Sprintf("h=%x", cell.hash[:cell.hashLen]))
- }
- b.WriteString("}")
- return b.String()
-}
-
func (cell *cell) FullString() string {
b := new(strings.Builder)
b.WriteString("{")
@@ -749,6 +731,176 @@ func (hph *HexPatriciaHashed) computeCellHashLen(cell *cell, depth int) int {
return length.Hash + 1
}
+func (hph *HexPatriciaHashed) computeCellHashWithStorage(cell *cell, depth int, buf []byte) ([]byte, bool, []byte, error) {
+ var err error
+ var storageRootHash [length.Hash]byte
+ var storageRootHashIsSet bool
+ if cell.storageAddrLen > 0 {
+ var hashedKeyOffset int
+ if depth >= 64 {
+ hashedKeyOffset = depth - 64
+ }
+ singleton := depth <= 64
+ koffset := hph.accountKeyLen
+ if depth == 0 && cell.accountAddrLen == 0 {
+ // if account key is empty, then we need to hash storage key from the key beginning
+ koffset = 0
+ }
+ if err = hashKey(hph.keccak, cell.storageAddr[koffset:cell.storageAddrLen], cell.hashedExtension[:], hashedKeyOffset, cell.hashBuf[:]); err != nil {
+ return nil, storageRootHashIsSet, nil, err
+ }
+ cell.hashedExtension[64-hashedKeyOffset] = 16 // Add terminator
+
+ if cell.stateHashLen > 0 {
+ res := append([]byte{160}, cell.stateHash[:cell.stateHashLen]...)
+ hph.keccak.Reset()
+ if hph.trace {
+ fmt.Printf("REUSED stateHash %x spk %x\n", res, cell.storageAddr[:cell.storageAddrLen])
+ }
+ mxTrieStateSkipRate.Inc()
+ skippedLoad.Add(1)
+ if !singleton {
+ return res, storageRootHashIsSet, nil, err
+ } else {
+ storageRootHashIsSet = true
+ storageRootHash = *(*[length.Hash]byte)(res[1:])
+ //copy(storageRootHash[:], res[1:])
+ //cell.stateHashLen = 0
+ }
+ } else {
+ if !cell.loaded.storage() {
+ update, err := hph.ctx.Storage(cell.storageAddr[:cell.storageAddrLen])
+ if err != nil {
+ return nil, storageRootHashIsSet, nil, err
+ }
+ cell.setFromUpdate(update)
+ fmt.Printf("Storage %x was not loaded\n", cell.storageAddr[:cell.storageAddrLen])
+ }
+ if singleton {
+ if hph.trace {
+ fmt.Printf("leafHashWithKeyVal(singleton) for [%x]=>[%x]\n", cell.hashedExtension[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen])
+ }
+ aux := make([]byte, 0, 33)
+ if aux, err = hph.leafHashWithKeyVal(aux, cell.hashedExtension[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen], true); err != nil {
+ return nil, storageRootHashIsSet, nil, err
+ }
+ if hph.trace {
+ fmt.Printf("leafHashWithKeyVal(singleton) storage hash [%x]\n", aux)
+ }
+ storageRootHash = *(*[length.Hash]byte)(aux[1:])
+ storageRootHashIsSet = true
+ cell.stateHashLen = 0
+ hadToReset.Add(1)
+ } else {
+ if hph.trace {
+ fmt.Printf("leafHashWithKeyVal for [%x]=>[%x] %v\n", cell.hashedExtension[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen], cell.String())
+ }
+ leafHash, err := hph.leafHashWithKeyVal(buf, cell.hashedExtension[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen], false)
+ if err != nil {
+ return nil, storageRootHashIsSet, nil, err
+ }
+
+ copy(cell.stateHash[:], leafHash[1:])
+ cell.stateHashLen = len(leafHash) - 1
+ if hph.trace {
+ fmt.Printf("STATE HASH storage memoized %x spk %x\n", leafHash, cell.storageAddr[:cell.storageAddrLen])
+ }
+
+ return leafHash, storageRootHashIsSet, storageRootHash[:], nil
+ }
+ }
+ }
+ if cell.accountAddrLen > 0 {
+ if err := hashKey(hph.keccak, cell.accountAddr[:cell.accountAddrLen], cell.hashedExtension[:], depth, cell.hashBuf[:]); err != nil {
+ return nil, storageRootHashIsSet, nil, err
+ }
+ cell.hashedExtension[64-depth] = 16 // Add terminator
+ if !storageRootHashIsSet {
+ if cell.extLen > 0 { // Extension
+ if cell.hashLen == 0 {
+ return nil, storageRootHashIsSet, nil, errors.New("computeCellHash extension without hash")
+ }
+ if hph.trace {
+ fmt.Printf("extensionHash for [%x]=>[%x]\n", cell.extension[:cell.extLen], cell.hash[:cell.hashLen])
+ }
+ if storageRootHash, err = hph.extensionHash(cell.extension[:cell.extLen], cell.hash[:cell.hashLen]); err != nil {
+ return nil, storageRootHashIsSet, nil, err
+ }
+ if hph.trace {
+ fmt.Printf("EXTENSION HASH %x DROPS stateHash\n", storageRootHash)
+ }
+ cell.stateHashLen = 0
+ hadToReset.Add(1)
+ } else if cell.hashLen > 0 {
+ storageRootHash = cell.hash
+ storageRootHashIsSet = true
+ } else {
+ storageRootHash = *(*[length.Hash]byte)(EmptyRootHash)
+ }
+ }
+ if !cell.loaded.account() {
+ if cell.stateHashLen > 0 {
+ res := append([]byte{160}, cell.stateHash[:cell.stateHashLen]...)
+ hph.keccak.Reset()
+
+ mxTrieStateSkipRate.Inc()
+ skippedLoad.Add(1)
+ if hph.trace {
+ fmt.Printf("REUSED stateHash %x apk %x\n", res, cell.accountAddr[:cell.accountAddrLen])
+ }
+ return res, storageRootHashIsSet, storageRootHash[:], nil
+ }
+ // storage root update or extension update could invalidate older stateHash, so we need to reload state
+ update, err := hph.ctx.Account(cell.accountAddr[:cell.accountAddrLen])
+ if err != nil {
+ return nil, storageRootHashIsSet, storageRootHash[:], err
+ }
+ cell.setFromUpdate(update)
+ }
+
+ var valBuf [128]byte
+ valLen := cell.accountForHashing(valBuf[:], storageRootHash)
+ if hph.trace {
+ fmt.Printf("accountLeafHashWithKey for [%x]=>[%x]\n", cell.hashedExtension[:65-depth], rlp.RlpEncodedBytes(valBuf[:valLen]))
+ }
+ leafHash, err := hph.accountLeafHashWithKey(buf, cell.hashedExtension[:65-depth], rlp.RlpEncodedBytes(valBuf[:valLen]))
+ if err != nil {
+ return nil, storageRootHashIsSet, nil, err
+ }
+ if hph.trace {
+ fmt.Printf("STATE HASH account memoized %x\n", leafHash)
+ }
+ copy(cell.stateHash[:], leafHash[1:])
+ cell.stateHashLen = len(leafHash) - 1
+ return leafHash, storageRootHashIsSet, storageRootHash[:], nil
+ }
+
+ buf = append(buf, 0x80+32)
+ if cell.extLen > 0 { // Extension
+ if cell.hashLen > 0 {
+ if hph.trace {
+ fmt.Printf("extensionHash for [%x]=>[%x]\n", cell.extension[:cell.extLen], cell.hash[:cell.hashLen])
+ }
+ var hash [length.Hash]byte
+ if hash, err = hph.extensionHash(cell.extension[:cell.extLen], cell.hash[:cell.hashLen]); err != nil {
+ return nil, storageRootHashIsSet, storageRootHash[:], err
+ }
+ buf = append(buf, hash[:]...)
+ } else {
+ return nil, storageRootHashIsSet, storageRootHash[:], errors.New("computeCellHash extension without hash")
+ }
+ } else if cell.hashLen > 0 {
+ buf = append(buf, cell.hash[:cell.hashLen]...)
+ } else if storageRootHashIsSet {
+ buf = append(buf, storageRootHash[:]...)
+ copy(cell.hash[:], storageRootHash[:])
+ cell.hashLen = len(storageRootHash)
+ } else {
+ buf = append(buf, EmptyRootHash...)
+ }
+ return buf, storageRootHashIsSet, storageRootHash[:], nil
+}
+
func (hph *HexPatriciaHashed) computeCellHash(cell *cell, depth int, buf []byte) ([]byte, error) {
var err error
var storageRootHash [length.Hash]byte
@@ -953,6 +1105,228 @@ func (hph *HexPatriciaHashed) needUnfolding(hashedKey []byte) int {
return unfolding
}
+func (c *cell) IsEmpty() bool {
+ return c.hashLen == 0 && c.hashedExtLen == 0 && c.extLen == 0 && c.accountAddrLen == 0 && c.storageAddrLen == 0
+}
+
+func (c *cell) String() string {
+ s := "("
+ if c.hashLen > 0 {
+ s += fmt.Sprintf("hash(len=%d)=%x, ", c.hashLen, c.hash)
+ }
+ if c.hashedExtLen > 0 {
+ s += fmt.Sprintf("hashedExtension(len=%d)=%x, ", c.hashedExtLen, c.hashedExtension[:c.hashedExtLen])
+ }
+ if c.extLen > 0 {
+ s += fmt.Sprintf("extension(len=%d)=%x, ", c.extLen, c.extension[:c.extLen])
+ }
+ if c.accountAddrLen > 0 {
+ s += fmt.Sprintf("accountAddr=%x, ", c.accountAddr)
+ }
+ if c.storageAddrLen > 0 {
+ s += fmt.Sprintf("storageAddr=%x, ", c.storageAddr)
+ }
+
+ s += ")"
+ return s
+}
+
+func (hph *HexPatriciaHashed) PrintGrid() {
+ fmt.Printf("GRID:\n")
+ for row := 0; row < hph.activeRows; row++ {
+ fmt.Printf("row %d depth %d:\n", row, hph.depths[row])
+ for col := 0; col < 16; col++ {
+ cell := &hph.grid[row][col]
+ if cell.hashedExtLen > 0 || cell.accountAddrLen > 0 {
+ var cellHash []byte
+ cellHash, _, _, err := hph.computeCellHashWithStorage(cell, hph.depths[row], nil)
+ if err != nil {
+ panic("failed to compute cell hash")
+ }
+ fmt.Printf("\t %x: %v cellHash=%x, \n", col, cell, cellHash)
+ } else {
+ fmt.Printf("\t %x: %v , \n", col, cell)
+ }
+ }
+ fmt.Printf("\n")
+ }
+ fmt.Printf("\n")
+}
+
+// this function is only related to the witness
+func (hph *HexPatriciaHashed) createAccountNode(c *cell, row int, hashedKey []byte, codeReads map[libcommon.Hash]witnesstypes.CodeWithHash) (*trie.AccountNode, error) {
+ _, storageIsSet, storageRootHash, err := hph.computeCellHashWithStorage(c, hph.depths[row], nil)
+ if err != nil {
+ return nil, err
+ }
+ accountUpdate, err := hph.ctx.Account(c.accountAddr[:c.accountAddrLen])
+ if err != nil {
+ return nil, err
+ }
+ var account accounts.Account
+ account.Nonce = accountUpdate.Nonce
+ account.Balance = accountUpdate.Balance
+ account.Initialised = true
+ account.Root = accountUpdate.Storage
+ account.CodeHash = accountUpdate.CodeHash
+
+ addrHash, err := compactKey(hashedKey[:64])
+ if err != nil {
+ return nil, err
+ }
+
+ // get code
+ var code []byte
+ codeWithHash, hasCode := codeReads[[32]byte(addrHash)]
+ if !hasCode {
+ code = nil
+ } else {
+ code = codeWithHash.Code
+ // sanity check
+ if account.CodeHash != codeWithHash.CodeHash {
+ return nil, fmt.Errorf("account.CodeHash(%x)!=codeReads[%x].CodeHash(%x)", account.CodeHash, addrHash, codeWithHash.CodeHash)
+ }
+ }
+
+ var accountNode *trie.AccountNode
+ if !storageIsSet {
+ account.Root = trie.EmptyRoot
+ accountNode = &trie.AccountNode{Account: account, Storage: nil, RootCorrect: true, Code: code, CodeSize: -1}
+ } else {
+ accountNode = &trie.AccountNode{Account: account, Storage: trie.NewHashNode(storageRootHash), RootCorrect: true, Code: code, CodeSize: -1}
+ }
+ return accountNode, nil
+}
+
+func (hph *HexPatriciaHashed) nCellsInRow(row int) int { //nolint:unused
+ count := 0
+ for col := 0; col < 16; col++ {
+ c := &hph.grid[row][col]
+ if !c.IsEmpty() {
+ count++
+ }
+ }
+ return count
+}
+
+// Traverse the grid following `hashedKey` and produce the witness `trie.Trie` for that key
+func (hph *HexPatriciaHashed) ToTrie(hashedKey []byte, codeReads map[libcommon.Hash]witnesstypes.CodeWithHash) (*trie.Trie, error) {
+ rootNode := &trie.FullNode{}
+ var currentNode trie.Node = rootNode
+ keyPos := 0 // current position in hashedKey (usually same as row, but could be different due to extension nodes)
+ for row := 0; row < hph.activeRows && keyPos < len(hashedKey); row++ {
+ currentNibble := hashedKey[keyPos]
+ // determine the type of the next node to expand (in the next iteration)
+ var nextNode trie.Node
+ // need to check node type along the key path
+ cellToExpand := &hph.grid[row][currentNibble]
+ // determine the next node
+ if cellToExpand.hashedExtLen > 0 { // extension cell
+ keyPos += cellToExpand.hashedExtLen // jump ahead
+ hashedExtKey := cellToExpand.hashedExtension[:cellToExpand.hashedExtLen]
+ extKeyLength := len(hashedExtKey)
+ if keyPos+1 == len(hashedKey) || keyPos+1 == 64 {
+ extKeyLength++ // +1 for the terminator 0x10 ([16]) byte when on a terminal extension node
+ }
+ extensionKey := make([]byte, extKeyLength)
+ copy(extensionKey, hashedExtKey)
+ if keyPos+1 == len(hashedKey) || keyPos+1 == 64 {
+ extensionKey[len(extensionKey)-1] = 16 // append terminator byte
+ }
+ nextNode = &trie.ShortNode{Key: extensionKey} // Value will be in the next iteration
+ if keyPos+1 == len(hashedKey) {
+ if cellToExpand.storageAddrLen > 0 {
+ storageUpdate, err := hph.ctx.Storage(cellToExpand.storageAddr[:cellToExpand.storageAddrLen])
+ if err != nil {
+ return nil, err
+ }
+ storageValueNode := trie.ValueNode(storageUpdate.Storage[:storageUpdate.StorageLen])
+ nextNode = &trie.ShortNode{Key: extensionKey, Val: storageValueNode}
+ } else if cellToExpand.accountAddrLen > 0 {
+ accNode, err := hph.createAccountNode(cellToExpand, row, hashedKey, codeReads)
+ if err != nil {
+ return nil, err
+ }
+ nextNode = &trie.ShortNode{Key: extensionKey, Val: accNode}
+ extNodeSubTrie := trie.NewInMemoryTrie(nextNode)
+ subTrieRoot := extNodeSubTrie.Root()
+ cellHash, _, _, _ := hph.computeCellHashWithStorage(cellToExpand, hph.depths[row], nil)
+ if !bytes.Equal(subTrieRoot, cellHash[1:]) {
+ return nil, fmt.Errorf("subTrieRoot(%x) != cellHash(%x)", subTrieRoot, cellHash[1:])
+ }
+ // // DEBUG patch with cell hash which we know to be correct
+ // nextNode = trie.NewHashNode(cellHash[1:])
+ }
+ }
+ } else if cellToExpand.storageAddrLen > 0 { // storage cell
+ storageUpdate, err := hph.ctx.Storage(cellToExpand.storageAddr[:cellToExpand.storageAddrLen])
+ if err != nil {
+ return nil, err
+ }
+ storageValueNode := trie.ValueNode(storageUpdate.Storage[:storageUpdate.StorageLen])
+ nextNode = &storageValueNode //nolint:ineffassign, wastedassign
+ break
+ } else if cellToExpand.accountAddrLen > 0 { // account cell
+ accNode, err := hph.createAccountNode(cellToExpand, row, hashedKey, codeReads)
+ if err != nil {
+ return nil, err
+ }
+ nextNode = accNode
+ keyPos++ // only move one nibble
+ } else if cellToExpand.hashLen > 0 { // hash cell means we will expand using a full node
+ nextNode = &trie.FullNode{}
+ keyPos++
+ } else if cellToExpand.IsEmpty() {
+ nextNode = nil // no more expanding can happen (this could be due )
+ } else { // default for now before we handle extLen
+ nextNode = &trie.FullNode{}
+ keyPos++
+ }
+
+ // process the current node
+ if fullNode, ok := currentNode.(*trie.FullNode); ok { // handle full node case
+ for col := 0; col < 16; col++ {
+ currentCell := &hph.grid[row][col]
+ if currentCell.IsEmpty() {
+ fullNode.Children[col] = nil
+ continue
+ }
+ cellHash, _, _, err := hph.computeCellHashWithStorage(currentCell, hph.depths[row], nil)
+ if err != nil {
+ return nil, err
+ }
+ fullNode.Children[col] = trie.NewHashNode(cellHash[1:]) // because cellHash has 33 bytes and we want 32
+ }
+ fullNode.Children[currentNibble] = nextNode // ready to expand next nibble in the path
+ } else if accNode, ok := currentNode.(*trie.AccountNode); ok {
+ if len(hashedKey) <= 64 { // no storage, stop here
+ nextNode = nil // nolint:ineffassign, wastedassign
+ break
+ }
+ // there is storage so we need to expand further
+ accNode.Storage = nextNode
+ } else if extNode, ok := currentNode.(*trie.ShortNode); ok { // handle extension node case
+ // expect only one item in this row, so take the first one
+ // technically it should be at the last nibble of the key but we will adjust this later
+ if extNode.Val != nil { // early termination
+ break
+ }
+ extNode.Val = nextNode
+ } else {
+ break // break if currentNode is nil
+ }
+ // we need to check if we are dealing with the next node being an account node and we have a storage key,
+ // in that case start a new tree for the storage
+ if nextAccNode, ok := nextNode.(*trie.AccountNode); ok && len(hashedKey) > 64 {
+ nextNode = &trie.FullNode{}
+ nextAccNode.Storage = nextNode
+ }
+ currentNode = nextNode
+ }
+ tr := trie.NewInMemoryTrie(rootNode)
+ return tr, nil
+}
+
// unfoldBranchNode returns true if unfolding has been done
func (hph *HexPatriciaHashed) unfoldBranchNode(row, depth int, deleted bool) (bool, error) {
key := hexToCompact(hph.currentKey[:hph.currentKeyLen])
@@ -1505,6 +1879,120 @@ func (hph *HexPatriciaHashed) RootHash() ([]byte, error) {
return rootHash[1:], nil // first byte is 128+hash_len=160
}
+// Generate the block witness. This works by loading each key from the list of updates (they are not really updates since we won't modify the trie,
+// but currently need to be defined like that for the fold/unfold algorithm) into the grid and traversing the grid to convert it into `trie.Trie`.
+// All the individual tries are combined to create the final witness trie.
+// Because the grid is lacking information about the code in smart contract accounts which is also part of the witness, we need to provide that as an input parameter to this function (`codeReads`)
+func (hph *HexPatriciaHashed) GenerateWitness(ctx context.Context, updates *Updates, codeReads map[libcommon.Hash]witnesstypes.CodeWithHash, expectedRootHash []byte, logPrefix string) (witnessTrie *trie.Trie, rootHash []byte, err error) {
+ var (
+ m runtime.MemStats
+ ki uint64
+
+ updatesCount = updates.Size()
+ logEvery = time.NewTicker(20 * time.Second)
+ )
+ defer logEvery.Stop()
+ var tries []*trie.Trie = make([]*trie.Trie, 0, len(updates.keys)) // slice of tries, i.e the witness for each key, these will be all merged into single trie
+ err = updates.HashSort(ctx, func(hashedKey, plainKey []byte, stateUpdate *Update) error {
+ select {
+ case <-logEvery.C:
+ dbg.ReadMemStats(&m)
+ log.Info(fmt.Sprintf("[%s][agg] computing trie", logPrefix),
+ "progress", fmt.Sprintf("%s/%s", common.PrettyCounter(ki), common.PrettyCounter(updatesCount)),
+ "alloc", common.ByteCount(m.Alloc), "sys", common.ByteCount(m.Sys))
+
+ default:
+ }
+
+ var tr *trie.Trie
+ var computedRootHash []byte
+
+ fmt.Printf("\n%d/%d) plainKey [%x] hashedKey [%x] currentKey [%x]\n", ki+1, updatesCount, plainKey, hashedKey, hph.currentKey[:hph.currentKeyLen])
+
+ if len(plainKey) == 20 { // account
+ account, err := hph.ctx.Account(plainKey)
+ if err != nil {
+ return fmt.Errorf("account with plainkey=%x not found: %w", plainKey, err)
+ } else {
+ addrHash := ecrypto.Keccak256(plainKey)
+ fmt.Printf("account with plainKey=%x, addrHash=%x FOUND = %v\n", plainKey, addrHash, account)
+ }
+ } else {
+ storage, err := hph.ctx.Storage(plainKey)
+ if err != nil {
+ return fmt.Errorf("storage with plainkey=%x not found: %w", plainKey, err)
+ }
+ fmt.Printf("storage found = %v\n", storage.Storage)
+ }
+
+ // Keep folding until the currentKey is the prefix of the key we modify
+ for hph.needFolding(hashedKey) {
+ if err := hph.fold(); err != nil {
+ return fmt.Errorf("fold: %w", err)
+ }
+ }
+ // Now unfold until we step on an empty cell
+ for unfolding := hph.needUnfolding(hashedKey); unfolding > 0; unfolding = hph.needUnfolding(hashedKey) {
+ if err := hph.unfold(hashedKey, unfolding); err != nil {
+ return fmt.Errorf("unfold: %w", err)
+ }
+ }
+ hph.PrintGrid()
+
+ // convert grid to trie.Trie
+ tr, err = hph.ToTrie(hashedKey, codeReads) // build witness trie for this key, based on the current state of the grid
+ if err != nil {
+ return err
+ }
+ computedRootHash = tr.Root()
+ fmt.Printf("computedRootHash = %x\n", computedRootHash)
+
+ if !bytes.Equal(computedRootHash, expectedRootHash) {
+ err = fmt.Errorf("root hash mismatch computedRootHash(%x)!=expectedRootHash(%x)", computedRootHash, expectedRootHash)
+ return err
+ }
+
+ tries = append(tries, tr)
+ ki++
+ return nil
+ })
+
+ if err != nil {
+ return nil, nil, fmt.Errorf("hash sort failed: %w", err)
+ }
+
+ // Folding everything up to the root
+ for hph.activeRows > 0 {
+ if err := hph.fold(); err != nil {
+ return nil, nil, fmt.Errorf("final fold: %w", err)
+ }
+ }
+
+ rootHash, err = hph.RootHash()
+ if err != nil {
+ return nil, nil, fmt.Errorf("root hash evaluation failed: %w", err)
+ }
+ if hph.trace {
+ fmt.Printf("root hash %x updates %d\n", rootHash, updatesCount)
+ }
+
+ // merge all individual tries
+ witnessTrie, err = trie.MergeTries(tries)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ witnessTrieRootHash := witnessTrie.Root()
+
+ fmt.Printf("mergedTrieRootHash = %x\n", witnessTrieRootHash)
+
+ if !bytes.Equal(witnessTrieRootHash, expectedRootHash) {
+ return nil, nil, fmt.Errorf("root hash mismatch witnessTrieRootHash(%x)!=expectedRootHash(%x)", witnessTrieRootHash, expectedRootHash)
+ }
+
+ return witnessTrie, rootHash, nil
+}
+
func (hph *HexPatriciaHashed) Process(ctx context.Context, updates *Updates, logPrefix string) (rootHash []byte, err error) {
var (
m runtime.MemStats
@@ -2126,7 +2614,7 @@ func commonPrefixLen(b1, b2 []byte) int {
// nolint
// Hashes provided key and expands resulting hash into nibbles (each byte split into two nibbles by 4 bits)
-func (hph *HexPatriciaHashed) hashAndNibblizeKey(key []byte) []byte {
+func (hph *HexPatriciaHashed) HashAndNibblizeKey(key []byte) []byte {
hashedKey := make([]byte, length.Hash)
hph.keccak.Reset()
@@ -2151,3 +2639,52 @@ func (hph *HexPatriciaHashed) hashAndNibblizeKey(key []byte) []byte {
}
return nibblized
}
+
+func nibblize(key []byte) []byte { // nolint:unused
+ nibblized := make([]byte, len(key)*2)
+ for i, b := range key {
+ nibblized[i*2] = (b >> 4) & 0xf
+ nibblized[i*2+1] = b & 0xf
+ }
+ return nibblized
+}
+
+// compactKey takes a slice of nibbles and compacts them into the original byte slice.
+// It returns an error if the input contains invalid nibbles (values > 0xF).
+func compactKey(nibbles []byte) ([]byte, error) {
+ // If the number of nibbles is odd, you might decide to handle it differently.
+ // For this example, we'll return an error.
+ if len(nibbles)%2 != 0 {
+ return nil, errors.New("nibbles slice has an odd length")
+ }
+
+ key := make([]byte, len(nibbles)/2)
+ for i := 0; i < len(key); i++ {
+ highNibble := nibbles[i*2]
+ lowNibble := nibbles[i*2+1]
+
+ // Validate that each nibble is indeed a nibble
+ if highNibble > 0xF || lowNibble > 0xF {
+ return nil, fmt.Errorf("invalid nibble at position %d or %d: 0x%X, 0x%X", i*2, i*2+1, highNibble, lowNibble)
+ }
+
+ key[i] = (highNibble << 4) | (lowNibble & 0x0F)
+ }
+ return key, nil
+}
+
+func (hph *HexPatriciaHashed) Grid() [128][16]cell {
+ return hph.grid
+}
+
+func (hph *HexPatriciaHashed) PrintAccountsInGrid() {
+ fmt.Printf("SEARCHING FOR ACCOUNTS IN GRID\n")
+ for row := 0; row < 128; row++ {
+ for col := 0; col < 16; col++ {
+ c := hph.grid[row][col]
+ if c.accountAddr[19] != 0 && c.accountAddr[0] != 0 {
+ fmt.Printf("FOUND account %x in position (%d,%d)\n", c.accountAddr, row, col)
+ }
+ }
+ }
+}
diff --git a/erigon-lib/commitment/hex_patricia_hashed_bench_test.go b/erigon-lib/commitment/hex_patricia_hashed_bench_test.go
index 3ccba659418..3db0373925c 100644
--- a/erigon-lib/commitment/hex_patricia_hashed_bench_test.go
+++ b/erigon-lib/commitment/hex_patricia_hashed_bench_test.go
@@ -49,7 +49,7 @@ func Benchmark_HexPatriciaHashed_Process(b *testing.B) {
require.NoError(b, err)
hph := NewHexPatriciaHashed(length.Addr, ms, ms.TempDir())
- upds := WrapKeyUpdates(b, ModeDirect, hph.hashAndNibblizeKey, nil, nil)
+ upds := WrapKeyUpdates(b, ModeDirect, hph.HashAndNibblizeKey, nil, nil)
defer upds.Close()
b.ResetTimer()
diff --git a/erigon-lib/commitment/hex_patricia_hashed_fuzz_test.go b/erigon-lib/commitment/hex_patricia_hashed_fuzz_test.go
index bbc16f9f18f..76d06d2d4cd 100644
--- a/erigon-lib/commitment/hex_patricia_hashed_fuzz_test.go
+++ b/erigon-lib/commitment/hex_patricia_hashed_fuzz_test.go
@@ -65,13 +65,13 @@ func Fuzz_ProcessUpdate(f *testing.F) {
err = ms2.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- upds := WrapKeyUpdates(t, ModeDirect, hph.hashAndNibblizeKey, nil, nil)
+ upds := WrapKeyUpdates(t, ModeDirect, hph.HashAndNibblizeKey, nil, nil)
rootHashDirect, err := hph.Process(ctx, upds, "")
require.NoError(t, err)
require.Len(t, rootHashDirect, length.Hash, "invalid root hash length")
upds.Close()
- anotherUpds := WrapKeyUpdates(t, ModeUpdate, hphAnother.hashAndNibblizeKey, nil, nil)
+ anotherUpds := WrapKeyUpdates(t, ModeUpdate, hphAnother.HashAndNibblizeKey, nil, nil)
rootHashUpdate, err := hphAnother.Process(ctx, anotherUpds, "")
require.NoError(t, err)
require.Len(t, rootHashUpdate, length.Hash, "invalid root hash length")
@@ -149,7 +149,7 @@ func Fuzz_ProcessUpdates_ArbitraryUpdateCount2(f *testing.F) {
err := ms.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsDirect := WrapKeyUpdates(t, ModeDirect, hph.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsDirect := WrapKeyUpdates(t, ModeDirect, hph.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
rootHashDirect, err := hph.Process(ctx, updsDirect, "")
updsDirect.Close()
require.NoError(t, err)
@@ -158,7 +158,7 @@ func Fuzz_ProcessUpdates_ArbitraryUpdateCount2(f *testing.F) {
err = ms2.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- upds := WrapKeyUpdates(t, ModeUpdate, hphAnother.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ upds := WrapKeyUpdates(t, ModeUpdate, hphAnother.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
rootHashAnother, err := hphAnother.Process(ctx, upds, "")
upds.Close()
require.NoError(t, err)
@@ -213,7 +213,7 @@ func Fuzz_HexPatriciaHashed_ReviewKeys(f *testing.F) {
t.Fatal(err)
}
- upds := WrapKeyUpdates(t, ModeDirect, hph.hashAndNibblizeKey, plainKeys, updates)
+ upds := WrapKeyUpdates(t, ModeDirect, hph.HashAndNibblizeKey, plainKeys, updates)
defer upds.Close()
rootHash, err := hph.Process(ctx, upds, "")
diff --git a/erigon-lib/commitment/hex_patricia_hashed_test.go b/erigon-lib/commitment/hex_patricia_hashed_test.go
index a8a129f818c..e2cc95bed09 100644
--- a/erigon-lib/commitment/hex_patricia_hashed_test.go
+++ b/erigon-lib/commitment/hex_patricia_hashed_test.go
@@ -53,7 +53,7 @@ func Test_HexPatriciaHashed_ResetThenSingularUpdates(t *testing.T) {
Storage("05", "04", "9898").
Build()
- upds := WrapKeyUpdates(t, ModeDirect, hph.hashAndNibblizeKey, plainKeys, updates)
+ upds := WrapKeyUpdates(t, ModeDirect, hph.HashAndNibblizeKey, plainKeys, updates)
defer upds.Close()
fmt.Printf("1. Generated %d updates\n", len(updates))
@@ -121,7 +121,7 @@ func Test_HexPatriciaHashed_EmptyUpdate(t *testing.T) {
err := ms.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- upds := WrapKeyUpdates(t, ModeDirect, hph.hashAndNibblizeKey, plainKeys, updates)
+ upds := WrapKeyUpdates(t, ModeDirect, hph.HashAndNibblizeKey, plainKeys, updates)
defer upds.Close()
hashBeforeEmptyUpdate, err := hph.Process(ctx, upds, "")
@@ -174,7 +174,7 @@ func Test_HexPatriciaHashed_UniqueRepresentation2(t *testing.T) {
err := msOne.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsOne := WrapKeyUpdates(t, ModeDirect, trieOne.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsOne := WrapKeyUpdates(t, ModeDirect, trieOne.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
sequentialRoot, err := trieOne.Process(ctx, updsOne, "")
require.NoError(t, err)
@@ -189,7 +189,7 @@ func Test_HexPatriciaHashed_UniqueRepresentation2(t *testing.T) {
err := msTwo.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updsTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.hashAndNibblizeKey, plainKeys, updates)
+ updsTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.HashAndNibblizeKey, plainKeys, updates)
fmt.Printf("\n2. Trie batch update (%d updates)\n", len(updates))
rh, err := trieTwo.Process(ctx, updsTwo, "")
@@ -215,7 +215,7 @@ func Test_HexPatriciaHashed_UniqueRepresentation2(t *testing.T) {
err := msOne.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsOne := WrapKeyUpdates(t, ModeDirect, trieOne.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsOne := WrapKeyUpdates(t, ModeDirect, trieOne.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
sequentialRoot, err := trieOne.Process(ctx, updsOne, "")
require.NoError(t, err)
@@ -231,7 +231,7 @@ func Test_HexPatriciaHashed_UniqueRepresentation2(t *testing.T) {
err := msTwo.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updsTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.hashAndNibblizeKey, plainKeys, updates)
+ updsTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.HashAndNibblizeKey, plainKeys, updates)
rh, err := trieTwo.Process(ctx, updsTwo, "")
require.NoError(t, err)
@@ -249,7 +249,7 @@ func sortUpdatesByHashIncrease(t *testing.T, hph *HexPatriciaHashed, plainKeys [
ku := make([]*KeyUpdate, len(plainKeys))
for i, pk := range plainKeys {
- ku[i] = &KeyUpdate{plainKey: string(pk), hashedKey: hph.hashAndNibblizeKey(pk), update: &updates[i]}
+ ku[i] = &KeyUpdate{plainKey: string(pk), hashedKey: hph.HashAndNibblizeKey(pk), update: &updates[i]}
}
sort.Slice(updates, func(i, j int) bool {
@@ -316,7 +316,7 @@ func Test_HexPatriciaHashed_BrokenUniqueRepr(t *testing.T) {
err := stateSeq.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsOne := WrapKeyUpdates(t, ModeDirect, trieSequential.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsOne := WrapKeyUpdates(t, ModeDirect, trieSequential.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
sequentialRoot, err := trieSequential.Process(ctx, updsOne, "")
require.NoError(t, err)
@@ -332,7 +332,7 @@ func Test_HexPatriciaHashed_BrokenUniqueRepr(t *testing.T) {
err := stateBatch.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updsTwo := WrapKeyUpdates(t, ModeDirect, trieBatch.hashAndNibblizeKey, plainKeys, updates)
+ updsTwo := WrapKeyUpdates(t, ModeDirect, trieBatch.HashAndNibblizeKey, plainKeys, updates)
rh, err := trieBatch.Process(ctx, updsTwo, "")
require.NoError(t, err)
@@ -399,7 +399,7 @@ func Test_HexPatriciaHashed_UniqueRepresentation(t *testing.T) {
err := stateSeq.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsOne := WrapKeyUpdates(t, ModeDirect, trieSequential.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsOne := WrapKeyUpdates(t, ModeDirect, trieSequential.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
sequentialRoot, err := trieSequential.Process(ctx, updsOne, "")
require.NoError(t, err)
@@ -415,7 +415,7 @@ func Test_HexPatriciaHashed_UniqueRepresentation(t *testing.T) {
err := stateBatch.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updsTwo := WrapKeyUpdates(t, ModeDirect, trieBatch.hashAndNibblizeKey, plainKeys, updates)
+ updsTwo := WrapKeyUpdates(t, ModeDirect, trieBatch.HashAndNibblizeKey, plainKeys, updates)
rh, err := trieBatch.Process(ctx, updsTwo, "")
require.NoError(t, err)
@@ -485,7 +485,7 @@ func Test_HexPatriciaHashed_Sepolia(t *testing.T) {
err := state.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- upds := WrapKeyUpdates(t, ModeDirect, hph.hashAndNibblizeKey, plainKeys, updates)
+ upds := WrapKeyUpdates(t, ModeDirect, hph.HashAndNibblizeKey, plainKeys, updates)
rootHash, err := hph.Process(ctx, upds, "")
require.NoError(t, err)
require.EqualValues(t, testData.expectedRoot, fmt.Sprintf("%x", rootHash))
@@ -598,7 +598,7 @@ func Test_HexPatriciaHashed_StateEncodeDecodeSetup(t *testing.T) {
err := ms.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- upds := WrapKeyUpdates(t, ModeDirect, before.hashAndNibblizeKey, plainKeys, updates)
+ upds := WrapKeyUpdates(t, ModeDirect, before.HashAndNibblizeKey, plainKeys, updates)
defer upds.Close()
// process updates
@@ -659,7 +659,7 @@ func Test_HexPatriciaHashed_StateRestoreAndContinue(t *testing.T) {
err = msTwo.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updOne := WrapKeyUpdates(t, ModeDirect, trieOne.hashAndNibblizeKey, plainKeys, updates)
+ updOne := WrapKeyUpdates(t, ModeDirect, trieOne.HashAndNibblizeKey, plainKeys, updates)
defer updOne.Close()
withoutRestore, err := trieOne.Process(ctx, updOne, "")
@@ -717,7 +717,7 @@ func Test_HexPatriciaHashed_StateRestoreAndContinue(t *testing.T) {
t.Logf("batch without restore (%d) root %x\n", len(updates), withoutRestore)
- updTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.hashAndNibblizeKey, plainKeys, updates)
+ updTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.HashAndNibblizeKey, plainKeys, updates)
defer updTwo.Close()
afterRestore, err := trieTwo.Process(ctx, updTwo, "")
@@ -758,7 +758,7 @@ func Test_HexPatriciaHashed_RestoreAndContinue(t *testing.T) {
err := ms.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updTwo := WrapKeyUpdates(t, ModeDirect, trieOne.hashAndNibblizeKey, plainKeys, updates)
+ updTwo := WrapKeyUpdates(t, ModeDirect, trieOne.HashAndNibblizeKey, plainKeys, updates)
defer updTwo.Close()
beforeRestore, err := trieTwo.Process(ctx, updTwo, "")
@@ -844,7 +844,7 @@ func Test_HexPatriciaHashed_ProcessUpdates_UniqueRepresentation_AfterStateRestor
err := stateSeq.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsOne := WrapKeyUpdates(t, ModeDirect, trieSequential.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsOne := WrapKeyUpdates(t, ModeDirect, trieSequential.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
sequentialRoot, err := trieSequential.Process(ctx, updsOne, "")
require.NoError(t, err)
@@ -871,7 +871,7 @@ func Test_HexPatriciaHashed_ProcessUpdates_UniqueRepresentation_AfterStateRestor
err := stateBatch.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updsTwo := WrapKeyUpdates(t, ModeDirect, trieBatch.hashAndNibblizeKey, plainKeys, updates)
+ updsTwo := WrapKeyUpdates(t, ModeDirect, trieBatch.HashAndNibblizeKey, plainKeys, updates)
rh, err := trieBatch.Process(ctx, updsTwo, "")
require.NoError(t, err)
@@ -944,7 +944,7 @@ func Test_HexPatriciaHashed_ProcessUpdates_UniqueRepresentationInTheMiddle(t *te
err := stateSeq.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsOne := WrapKeyUpdates(t, ModeDirect, sequential.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsOne := WrapKeyUpdates(t, ModeDirect, sequential.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
sequentialRoot, err := sequential.Process(ctx, updsOne, "")
require.NoError(t, err)
@@ -972,7 +972,7 @@ func Test_HexPatriciaHashed_ProcessUpdates_UniqueRepresentationInTheMiddle(t *te
err := stateBatch.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updsTwo := WrapKeyUpdates(t, ModeDirect, batch.hashAndNibblizeKey, plainKeys[:somewhere+1], updates[:somewhere+1])
+ updsTwo := WrapKeyUpdates(t, ModeDirect, batch.HashAndNibblizeKey, plainKeys[:somewhere+1], updates[:somewhere+1])
rh, err := batch.Process(ctx, updsTwo, "")
require.NoError(t, err)
@@ -1276,7 +1276,7 @@ func Test_HexPatriciaHashed_ProcessWithDozensOfStorageKeys(t *testing.T) {
//prefixesCnt := make(map[string]int)
//for i := 0; i < 5000000; i++ {
// rnd.Read(noise)
- // //hashed := trieOne.hashAndNibblizeKey(noise)
+ // //hashed := trieOne.HashAndNibblizeKey(noise)
// trieOne.keccak.Reset()
// trieOne.keccak.Write(noise)
// hashed := make([]byte, 32)
@@ -1310,7 +1310,7 @@ func Test_HexPatriciaHashed_ProcessWithDozensOfStorageKeys(t *testing.T) {
err := msOne.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1])
require.NoError(t, err)
- updsOne := WrapKeyUpdates(t, ModeDirect, trieOne.hashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
+ updsOne := WrapKeyUpdates(t, ModeDirect, trieOne.HashAndNibblizeKey, plainKeys[i:i+1], updates[i:i+1])
sequentialRoot, err := trieOne.Process(ctx, updsOne, "")
require.NoError(t, err)
@@ -1325,7 +1325,7 @@ func Test_HexPatriciaHashed_ProcessWithDozensOfStorageKeys(t *testing.T) {
err := msTwo.applyPlainUpdates(plainKeys, updates)
require.NoError(t, err)
- updsTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.hashAndNibblizeKey, plainKeys, updates)
+ updsTwo := WrapKeyUpdates(t, ModeDirect, trieTwo.HashAndNibblizeKey, plainKeys, updates)
fmt.Printf("\n2. Trie batch update (%d updates)\n", len(updates))
rh, err := trieTwo.Process(ctx, updsTwo, "")
diff --git a/erigon-lib/downloader/README.md b/erigon-lib/downloader/README.md
index 515fc0f6d21..d262447af52 100644
--- a/erigon-lib/downloader/README.md
+++ b/erigon-lib/downloader/README.md
@@ -53,7 +53,7 @@ When a `snapshot-lock` file exists it is used rather than the chain.toml file to
### Deleting snapshot-lock.json
-If the snapshot-lock file is deleted it will be reacreated from the `chain.toml` file embeded in the Erigon process. If the hashes change then the associated files will be re-downloaded.
+If the snapshot-lock file is deleted it will be recreated from the `chain.toml` file embedded in the Erigon process. If the hashes change then the associated files will be re-downloaded.
### How to override downloads
diff --git a/erigon-lib/etl/README.md b/erigon-lib/etl/README.md
index 8813501a42f..7d796282c79 100644
--- a/erigon-lib/etl/README.md
+++ b/erigon-lib/etl/README.md
@@ -8,7 +8,7 @@ Inserting entries into our KV storage sorted by keys helps to minimize write
amplification, hence it is much faster, even considering additional I/O that
is generated by storing files.
-It behaves similarly to enterprise [Extract, Tranform, Load](https://en.wikipedia.org/wiki/Extract,_transform,_load) frameworks, hence the name.
+It behaves similarly to enterprise [Extract, Transform, Load](https://en.wikipedia.org/wiki/Extract,_transform,_load) frameworks, hence the name.
We use temporary files because that helps keep RAM usage predictable and allows
using ETL on large amounts of data.
diff --git a/erigon-lib/go.mod b/erigon-lib/go.mod
index 41427eac8fe..2d96fdd3bf9 100644
--- a/erigon-lib/go.mod
+++ b/erigon-lib/go.mod
@@ -9,7 +9,7 @@ replace (
require (
github.com/erigontech/erigon-snapshot v1.3.1-0.20241023024258-f64407a77e8e
- github.com/erigontech/interfaces v0.0.0-20241116035842-5d396f10468e
+ github.com/erigontech/interfaces v0.0.0-20241120074553-214b5fd396ed
github.com/erigontech/mdbx-go v0.38.4
github.com/erigontech/secp256k1 v1.1.0
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417
@@ -36,7 +36,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/holiman/bloomfilter/v2 v2.0.3
- github.com/holiman/uint256 v1.3.1
+ github.com/holiman/uint256 v1.3.2
github.com/nyaosorg/go-windows-shortcut v0.0.0-20220529122037-8b0c89bca4c4
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
github.com/pelletier/go-toml/v2 v2.2.3
@@ -47,6 +47,7 @@ require (
github.com/spaolacci/murmur3 v1.1.0
github.com/stretchr/testify v1.9.0
github.com/tidwall/btree v1.6.0
+ github.com/ugorji/go/codec v1.2.12
go.uber.org/mock v0.5.0
golang.org/x/crypto v0.29.0
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
diff --git a/erigon-lib/go.sum b/erigon-lib/go.sum
index 79ffc1d5467..3559d3e1e95 100644
--- a/erigon-lib/go.sum
+++ b/erigon-lib/go.sum
@@ -152,8 +152,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/erigontech/erigon-snapshot v1.3.1-0.20241023024258-f64407a77e8e h1:ZpIO6HeopuZPYDLldL6zR0qyRezj80kQrDOGEF779ts=
github.com/erigontech/erigon-snapshot v1.3.1-0.20241023024258-f64407a77e8e/go.mod h1:ooHlCl+eEYzebiPu+FP6Q6SpPUeMADn8Jxabv3IKb9M=
-github.com/erigontech/interfaces v0.0.0-20241116035842-5d396f10468e h1:KD/yuduvNJDKkdmEaaiDYb9RQstnkJn5ZcSZHjH/C/w=
-github.com/erigontech/interfaces v0.0.0-20241116035842-5d396f10468e/go.mod h1:N7OUkhkcagp9+7yb4ycHsG2VWCOmuJ1ONBecJshxtLE=
+github.com/erigontech/interfaces v0.0.0-20241120074553-214b5fd396ed h1:un44S8Tuol4LBIC6R94t93GShM53BYjz7GsNPziDLQ8=
+github.com/erigontech/interfaces v0.0.0-20241120074553-214b5fd396ed/go.mod h1:N7OUkhkcagp9+7yb4ycHsG2VWCOmuJ1ONBecJshxtLE=
github.com/erigontech/mdbx-go v0.38.4 h1:S9T7mTe9KPcFe4dOoOtVdI6gPzht9y7wMnYfUBgrQLo=
github.com/erigontech/mdbx-go v0.38.4/go.mod h1:IcOLQDPw3VM/asP6T5JVPPN4FHHgJtY16XfYjzWKVNI=
github.com/erigontech/secp256k1 v1.1.0 h1:mO3YJMUSoASE15Ya//SoHiisptUhdXExuMUN1M0X9qY=
@@ -261,8 +261,8 @@ github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFO
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
-github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs=
-github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
+github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
+github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
@@ -476,6 +476,8 @@ github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZ
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
+github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
diff --git a/erigon-lib/gointerfaces/remoteproto/ethbackend.pb.go b/erigon-lib/gointerfaces/remoteproto/ethbackend.pb.go
index 62a4302d0b0..fbef7e8dd8f 100644
--- a/erigon-lib/gointerfaces/remoteproto/ethbackend.pb.go
+++ b/erigon-lib/gointerfaces/remoteproto/ethbackend.pb.go
@@ -1310,6 +1310,7 @@ type TxnLookupReply struct {
unknownFields protoimpl.UnknownFields
BlockNumber uint64 `protobuf:"varint,1,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"`
+ TxNumber uint64 `protobuf:"varint,2,opt,name=tx_number,json=txNumber,proto3" json:"tx_number,omitempty"`
}
func (x *TxnLookupReply) Reset() {
@@ -1351,6 +1352,13 @@ func (x *TxnLookupReply) GetBlockNumber() uint64 {
return 0
}
+func (x *TxnLookupReply) GetTxNumber() uint64 {
+ if x != nil {
+ return x.TxNumber
+ }
+ return 0
+}
+
type NodesInfoRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1916,131 +1924,133 @@ var file_remote_ethbackend_proto_rawDesc = []byte{
0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a,
0x08, 0x74, 0x78, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x48, 0x32, 0x35, 0x36, 0x52, 0x07, 0x74, 0x78,
- 0x6e, 0x48, 0x61, 0x73, 0x68, 0x22, 0x33, 0x0a, 0x0e, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b,
+ 0x6e, 0x48, 0x61, 0x73, 0x68, 0x22, 0x50, 0x0a, 0x0e, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b,
0x75, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62,
- 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x28, 0x0a, 0x10, 0x4e, 0x6f,
- 0x64, 0x65, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14,
- 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c,
- 0x69, 0x6d, 0x69, 0x74, 0x22, 0x22, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x45, 0x0a, 0x0e, 0x4e, 0x6f, 0x64, 0x65,
- 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, 0x0a, 0x6e, 0x6f,
- 0x64, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14,
- 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52,
- 0x65, 0x70, 0x6c, 0x79, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x22,
- 0x33, 0x0a, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x25, 0x0a,
- 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74,
- 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x70,
- 0x65, 0x65, 0x72, 0x73, 0x22, 0x28, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52,
- 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x30,
- 0x0a, 0x11, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65,
- 0x70, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6c, 0x70,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6c, 0x70,
- 0x22, 0x4c, 0x0a, 0x25, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79,
- 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68,
- 0x56, 0x31, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x06, 0x68, 0x61, 0x73,
- 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65,
- 0x73, 0x2e, 0x48, 0x32, 0x35, 0x36, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x54,
- 0x0a, 0x26, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f,
- 0x61, 0x64, 0x42, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x42, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x56,
- 0x31, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72,
- 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14,
- 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x2a, 0x4a, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a,
- 0x06, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x45, 0x4e,
- 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x4f, 0x47, 0x53, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50,
- 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x10,
- 0x0a, 0x0c, 0x4e, 0x45, 0x57, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x03,
- 0x32, 0xd3, 0x0a, 0x0a, 0x0a, 0x45, 0x54, 0x48, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x12,
- 0x3d, 0x0a, 0x09, 0x45, 0x74, 0x68, 0x65, 0x72, 0x62, 0x61, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x72,
- 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x62, 0x61, 0x73, 0x65, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e,
- 0x45, 0x74, 0x68, 0x65, 0x72, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x40,
- 0x0a, 0x0a, 0x4e, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x72,
- 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x4e, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65,
- 0x2e, 0x4e, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79,
- 0x12, 0x46, 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74,
- 0x12, 0x1b, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x4e, 0x65, 0x74, 0x50, 0x65, 0x65,
- 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x78,
+ 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x74,
+ 0x78, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x28, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x73,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c,
+ 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69,
+ 0x74, 0x22, 0x22, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x45, 0x0a, 0x0e, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x49, 0x6e,
+ 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x73,
+ 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79,
+ 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c,
+ 0x79, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x33, 0x0a, 0x0a,
+ 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x25, 0x0a, 0x05, 0x70, 0x65,
+ 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65,
+ 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72,
+ 0x73, 0x22, 0x28, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c,
+ 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x30, 0x0a, 0x11, 0x50,
+ 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79,
+ 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6c, 0x70, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6c, 0x70, 0x22, 0x4c, 0x0a,
+ 0x25, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
+ 0x64, 0x42, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x56, 0x31, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x48,
+ 0x32, 0x35, 0x36, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x26, 0x45,
+ 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42,
+ 0x6f, 0x64, 0x69, 0x65, 0x73, 0x42, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x56, 0x31, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e,
+ 0x74, 0x2a, 0x4a, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x45,
+ 0x41, 0x44, 0x45, 0x52, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e,
+ 0x47, 0x5f, 0x4c, 0x4f, 0x47, 0x53, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x45, 0x4e, 0x44,
+ 0x49, 0x4e, 0x47, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4e,
+ 0x45, 0x57, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x03, 0x32, 0xd3, 0x0a,
+ 0x0a, 0x0a, 0x45, 0x54, 0x48, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x12, 0x3d, 0x0a, 0x09,
+ 0x45, 0x74, 0x68, 0x65, 0x72, 0x62, 0x61, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x2e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x45, 0x74, 0x68,
+ 0x65, 0x72, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x40, 0x0a, 0x0a, 0x4e,
+ 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x2e, 0x4e, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x4e, 0x65,
+ 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x46, 0x0a,
+ 0x0c, 0x4e, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x2e,
0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x4e, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f,
- 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x74, 0x79,
- 0x70, 0x65, 0x73, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79,
- 0x12, 0x37, 0x0a, 0x07, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
- 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x53, 0x79, 0x6e,
- 0x63, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x4f, 0x0a, 0x0f, 0x50, 0x72, 0x6f,
- 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x72,
- 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x72,
- 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x49, 0x0a, 0x0d, 0x43, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x72, 0x65,
- 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
- 0x74, 0x65, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3f, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
- 0x62, 0x65, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x73,
- 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72,
- 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52,
- 0x65, 0x70, 0x6c, 0x79, 0x30, 0x01, 0x12, 0x4a, 0x0a, 0x0d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
- 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65,
- 0x2e, 0x4c, 0x6f, 0x67, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x73,
- 0x63, 0x72, 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x28, 0x01,
- 0x30, 0x01, 0x12, 0x31, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x2e, 0x72, 0x65,
- 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
- 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x67, 0x0a, 0x17, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63,
- 0x61, 0x6c, 0x42, 0x6f, 0x64, 0x79, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
- 0x12, 0x26, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69,
- 0x63, 0x61, 0x6c, 0x42, 0x6f, 0x64, 0x79, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
- 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74,
- 0x65, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x42, 0x6f, 0x64, 0x79, 0x46,
- 0x6f, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x49,
- 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12,
- 0x1c, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63,
- 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
+ 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x6d,
+ 0x6f, 0x74, 0x65, 0x2e, 0x4e, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+ 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+ 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73,
+ 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x37, 0x0a,
+ 0x07, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
+ 0x1a, 0x14, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e,
+ 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x4f, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+ 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x49, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74,
+ 0x65, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e,
+ 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70,
+ 0x6c, 0x79, 0x12, 0x3f, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12,
+ 0x18, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
+ 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x70, 0x6c,
+ 0x79, 0x30, 0x01, 0x12, 0x4a, 0x0a, 0x0d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
+ 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x4c, 0x6f,
+ 0x67, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+ 0x1a, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
+ 0x62, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x28, 0x01, 0x30, 0x01, 0x12,
+ 0x31, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74,
+ 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
+ 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x70,
+ 0x6c, 0x79, 0x12, 0x67, 0x0a, 0x17, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x42,
+ 0x6f, 0x64, 0x79, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x26, 0x2e,
0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c,
- 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x46, 0x0a, 0x0c, 0x48, 0x65, 0x61,
- 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
- 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e,
- 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c,
- 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12, 0x18,
- 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75,
- 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74,
- 0x65, 0x2e, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x79,
- 0x12, 0x3c, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x72,
- 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e,
- 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33,
- 0x0a, 0x05, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
- 0x12, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65,
- 0x70, 0x6c, 0x79, 0x12, 0x37, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x16,
- 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e,
- 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x41, 0x0a, 0x0c,
- 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
- 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x50, 0x65,
- 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12,
- 0x46, 0x0a, 0x0c, 0x42, 0x6f, 0x72, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12,
- 0x1b, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x72, 0x54, 0x78, 0x6e, 0x4c,
- 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72,
+ 0x42, 0x6f, 0x64, 0x79, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43,
+ 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x42, 0x6f, 0x64, 0x79, 0x46, 0x6f, 0x72, 0x53,
+ 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x49, 0x0a, 0x0d, 0x43,
+ 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x2e, 0x72,
+ 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x48,
+ 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x65, 0x6d,
+ 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x48, 0x61, 0x73,
+ 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x46, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
+ 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e,
+ 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61,
+ 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3d,
+ 0x0a, 0x09, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12, 0x18, 0x2e, 0x72, 0x65,
+ 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x54,
+ 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3c, 0x0a,
+ 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x4e, 0x6f, 0x64,
+ 0x65, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x50,
+ 0x65, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x72,
+ 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
+ 0x12, 0x37, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x72, 0x65,
+ 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x41, 0x64, 0x64,
+ 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x50, 0x65, 0x6e,
+ 0x64, 0x69, 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
+ 0x79, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69,
+ 0x6e, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x46, 0x0a, 0x0c,
+ 0x42, 0x6f, 0x72, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12, 0x1b, 0x2e, 0x72,
0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x72, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b,
- 0x75, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x42, 0x6f, 0x72, 0x45, 0x76,
- 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6f,
- 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
- 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74,
- 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x16, 0x5a, 0x14, 0x2e, 0x2f, 0x72, 0x65, 0x6d, 0x6f,
- 0x74, 0x65, 0x3b, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x72, 0x54, 0x78, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52,
+ 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x42, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74,
+ 0x73, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x72, 0x45, 0x76,
+ 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65,
+ 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65,
+ 0x70, 0x6c, 0x79, 0x42, 0x16, 0x5a, 0x14, 0x2e, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x3b,
+ 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33,
}
var (
diff --git a/erigon-lib/gointerfaces/remoteproto/kv_grpc.pb.go b/erigon-lib/gointerfaces/remoteproto/kv_grpc.pb.go
index f64ddddf7e7..8179df4b950 100644
--- a/erigon-lib/gointerfaces/remoteproto/kv_grpc.pb.go
+++ b/erigon-lib/gointerfaces/remoteproto/kv_grpc.pb.go
@@ -7,13 +7,12 @@
package remoteproto
import (
- "context"
-
- "github.com/erigontech/erigon-lib/gointerfaces/typesproto"
- "google.golang.org/grpc"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/status"
- "google.golang.org/protobuf/types/known/emptypb"
+ context "context"
+ typesproto "github.com/erigontech/erigon-lib/gointerfaces/typesproto"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// This is a compile-time assertion to ensure that this generated file
diff --git a/erigon-lib/kv/dbutils/composite_keys.go b/erigon-lib/kv/dbutils/composite_keys.go
index a98152fb512..611aa8c530d 100644
--- a/erigon-lib/kv/dbutils/composite_keys.go
+++ b/erigon-lib/kv/dbutils/composite_keys.go
@@ -75,3 +75,116 @@ func GenerateCompositeTrieKey(addressHash libcommon.Hash, seckey libcommon.Hash)
compositeKey = append(compositeKey, seckey[:]...)
return compositeKey
}
+
+// Address + storageLocationHash
+func GenerateStoragePlainKey(address libcommon.Address, storageKey libcommon.Hash) []byte {
+ storagePlainKey := make([]byte, 0, length.Addr+length.Hash)
+ storagePlainKey = append(storagePlainKey, address.Bytes()...)
+ storagePlainKey = append(storagePlainKey, storageKey.Bytes()...)
+ return storagePlainKey
+}
+
+// AddrHash + incarnation + KeyHash
+// For contract storage
+func GenerateCompositeStorageKey(addressHash libcommon.Hash, incarnation uint64, seckey libcommon.Hash) []byte {
+ compositeKey := make([]byte, length.Hash+length.Incarnation+length.Hash)
+ copy(compositeKey, addressHash[:])
+ binary.BigEndian.PutUint64(compositeKey[length.Hash:], incarnation)
+ copy(compositeKey[length.Hash+length.Incarnation:], seckey[:])
+ return compositeKey
+}
+
+func ParseCompositeStorageKey(compositeKey []byte) (libcommon.Hash, uint64, libcommon.Hash) {
+ prefixLen := length.Hash + length.Incarnation
+ addrHash, inc := ParseStoragePrefix(compositeKey[:prefixLen])
+ var key libcommon.Hash
+ copy(key[:], compositeKey[prefixLen:prefixLen+length.Hash])
+ return addrHash, inc, key
+}
+
+// AddrHash + incarnation + KeyHash
+// For contract storage (for plain state)
+func PlainGenerateCompositeStorageKey(address []byte, incarnation uint64, key []byte) []byte {
+ compositeKey := make([]byte, length.Addr+length.Incarnation+length.Hash)
+ copy(compositeKey, address)
+ binary.BigEndian.PutUint64(compositeKey[length.Addr:], incarnation)
+ copy(compositeKey[length.Addr+length.Incarnation:], key)
+ return compositeKey
+}
+
+func PlainParseCompositeStorageKey(compositeKey []byte) (libcommon.Address, uint64, libcommon.Hash) {
+ prefixLen := length.Addr + length.Incarnation
+ addr, inc := PlainParseStoragePrefix(compositeKey[:prefixLen])
+ var key libcommon.Hash
+ copy(key[:], compositeKey[prefixLen:prefixLen+length.Hash])
+ return addr, inc, key
+}
+
+// AddrHash + incarnation + StorageHashPrefix
+func GenerateCompositeStoragePrefix(addressHash []byte, incarnation uint64, storageHashPrefix []byte) []byte {
+ key := make([]byte, length.Hash+length.Incarnation+len(storageHashPrefix))
+ copy(key, addressHash)
+ binary.BigEndian.PutUint64(key[length.Hash:], incarnation)
+ copy(key[length.Hash+length.Incarnation:], storageHashPrefix)
+ return key
+}
+
+// address hash + incarnation prefix
+func GenerateStoragePrefix(addressHash []byte, incarnation uint64) []byte {
+ prefix := make([]byte, length.Hash+NumberLength)
+ copy(prefix, addressHash)
+ binary.BigEndian.PutUint64(prefix[length.Hash:], incarnation)
+ return prefix
+}
+
+// address hash + incarnation prefix (for plain state)
+func PlainGenerateStoragePrefix(address []byte, incarnation uint64) []byte {
+ prefix := make([]byte, length.Addr+NumberLength)
+ copy(prefix, address)
+ binary.BigEndian.PutUint64(prefix[length.Addr:], incarnation)
+ return prefix
+}
+
+func PlainParseStoragePrefix(prefix []byte) (libcommon.Address, uint64) {
+ var addr libcommon.Address
+ copy(addr[:], prefix[:length.Addr])
+ inc := binary.BigEndian.Uint64(prefix[length.Addr : length.Addr+length.Incarnation])
+ return addr, inc
+}
+
+func ParseStoragePrefix(prefix []byte) (libcommon.Hash, uint64) {
+ var addrHash libcommon.Hash
+ copy(addrHash[:], prefix[:length.Hash])
+ inc := binary.BigEndian.Uint64(prefix[length.Hash : length.Hash+length.Incarnation])
+ return addrHash, inc
+}
+
+// Key + blockNum
+func CompositeKeySuffix(key []byte, timestamp uint64) (composite, encodedTS []byte) {
+ encodedTS = encodeTimestamp(timestamp)
+ composite = make([]byte, len(key)+len(encodedTS))
+ copy(composite, key)
+ copy(composite[len(key):], encodedTS)
+ return composite, encodedTS
+}
+
+// encodeTimestamp has the property: if a < b, then Encoding(a) < Encoding(b) lexicographically
+func encodeTimestamp(timestamp uint64) []byte {
+ var suffix []byte
+ var limit uint64 = 32
+
+ for bytecount := 1; bytecount <= 8; bytecount++ {
+ if timestamp < limit {
+ suffix = make([]byte, bytecount)
+ b := timestamp
+ for i := bytecount - 1; i > 0; i-- {
+ suffix[i] = byte(b & 0xff)
+ b >>= 8
+ }
+ suffix[0] = byte(b) | (byte(bytecount) << 5) // 3 most significant bits of the first byte are bytecount
+ break
+ }
+ limit <<= 8
+ }
+ return suffix
+}
diff --git a/erigon-lib/kv/stream/stream_interface.go b/erigon-lib/kv/stream/stream_interface.go
index 6974c58e468..819154853a0 100644
--- a/erigon-lib/kv/stream/stream_interface.go
+++ b/erigon-lib/kv/stream/stream_interface.go
@@ -16,6 +16,8 @@
package stream
+import "errors"
+
// Streams - it's iterator-like composable high-level abstraction - which designed for inter-process communication and between processes:
// - cancelable
// - return errors
@@ -38,6 +40,10 @@ package stream
// check in loops on stream. Duo has very limited API - user has no way to
// terminate it - but user can specify more strict conditions when creating stream (then server knows better when to stop)
+// Indicates the iterator has no more elements. Meant to be returned by implementations of Next()
+// when there are no more elements.
+var ErrIteratorExhausted = errors.New("iterator exhausted")
+
// Uno - return 1 item. Example:
//
// for s.HasNext() {
diff --git a/erigon-lib/kv/tables.go b/erigon-lib/kv/tables.go
index baa140747a0..0d12d2563de 100644
--- a/erigon-lib/kv/tables.go
+++ b/erigon-lib/kv/tables.go
@@ -60,6 +60,8 @@ const (
ContractCode = "HashedCodeHash"
)
+const Witnesses = "witnesses" // block_num_u64 + "_chunk_" + chunk_num_u64 -> witness ( see: docs/programmers_guide/witness_format.md )
+
// Mapping [block number] => [Verkle Root]
const VerkleRoots = "VerkleRoots"
@@ -128,6 +130,8 @@ const (
ConfigTable = "Config" // config prefix for the db
+ PreimagePrefix = "SecureKey" // preimagePrefix + hash -> preima
+
// Progress of sync stages: stageName -> stageData
SyncStageProgress = "SyncStage"
@@ -287,8 +291,6 @@ const (
InactivityScores = "InactivityScores"
NextSyncCommittee = "NextSyncCommittee"
CurrentSyncCommittee = "CurrentSyncCommittee"
- HistoricalRoots = "HistoricalRoots"
- HistoricalSummaries = "HistoricalSummaries"
Eth1DataVotes = "Eth1DataVotes"
IntraRandaoMixes = "IntraRandaoMixes" // [validator_index+slot] => [randao_mix]
@@ -430,8 +432,6 @@ var ChaindataTables = []string{
// Blob Storage
BlockRootToKzgCommitments,
// State Reconstitution
- ValidatorPublicKeys,
- InvertedValidatorPublicKeys,
ValidatorEffectiveBalance,
ValidatorBalance,
ValidatorSlashings,
@@ -448,14 +448,11 @@ var ChaindataTables = []string{
InactivityScores,
NextSyncCommittee,
CurrentSyncCommittee,
- HistoricalRoots,
- HistoricalSummaries,
Eth1DataVotes,
IntraRandaoMixes,
ActiveValidatorIndicies,
EffectiveBalancesDump,
BalancesDump,
-
AccountChangeSetDeprecated,
StorageChangeSetDeprecated,
HashedAccountsDeprecated,
diff --git a/erigon-lib/recsplit/eliasfano32/elias_fano.go b/erigon-lib/recsplit/eliasfano32/elias_fano.go
index 37580963e5c..fb00f12b300 100644
--- a/erigon-lib/recsplit/eliasfano32/elias_fano.go
+++ b/erigon-lib/recsplit/eliasfano32/elias_fano.go
@@ -18,7 +18,6 @@ package eliasfano32
import (
"encoding/binary"
- "errors"
"fmt"
"io"
"math"
@@ -27,6 +26,7 @@ import (
"unsafe"
"github.com/erigontech/erigon-lib/common/bitutil"
+ "github.com/erigontech/erigon-lib/kv/stream"
)
// EliasFano algo overview https://www.antoniomallia.it/sorted-integers-compression-with-elias-fano-encoding.html
@@ -44,8 +44,6 @@ const (
superQSize uint64 = 1 + qPerSuperQ/2 // 1 + 64/2 = 33
)
-var ErrEliasFanoIterExhausted = errors.New("elias fano iterator exhausted")
-
// EliasFano can be used to encode one monotone sequence
type EliasFano struct {
data []uint64
@@ -486,7 +484,7 @@ func (efi *EliasFanoIter) decrement() {
func (efi *EliasFanoIter) Next() (uint64, error) {
if !efi.HasNext() {
- return 0, ErrEliasFanoIterExhausted
+ return 0, stream.ErrIteratorExhausted
}
idx64, shift := efi.lowerIdx/64, efi.lowerIdx%64
lower := efi.lowerBits[idx64] >> shift
diff --git a/erigon-lib/recsplit/eliasfano32/elias_fano_test.go b/erigon-lib/recsplit/eliasfano32/elias_fano_test.go
index 89ec594603e..89976581072 100644
--- a/erigon-lib/recsplit/eliasfano32/elias_fano_test.go
+++ b/erigon-lib/recsplit/eliasfano32/elias_fano_test.go
@@ -355,7 +355,7 @@ func TestIterator(t *testing.T) {
require.NoError(t, err)
}
_, err := it.Next()
- require.ErrorIs(t, err, ErrEliasFanoIterExhausted)
+ require.ErrorIs(t, err, stream.ErrIteratorExhausted)
it = ef.ReverseIterator()
for range offsets {
@@ -363,7 +363,7 @@ func TestIterator(t *testing.T) {
require.NoError(t, err)
}
_, err = it.Next()
- require.ErrorIs(t, err, ErrEliasFanoIterExhausted)
+ require.ErrorIs(t, err, stream.ErrIteratorExhausted)
})
t.Run("article-example1", func(t *testing.T) {
diff --git a/erigon-lib/state/domain.go b/erigon-lib/state/domain.go
index 4e70ed9f71f..328c25d1f0e 100644
--- a/erigon-lib/state/domain.go
+++ b/erigon-lib/state/domain.go
@@ -1703,7 +1703,8 @@ func (dt *DomainRoTx) statelessBtree(i int) *BtIndex {
func (dt *DomainRoTx) valsCursor(tx kv.Tx) (c kv.Cursor, err error) {
if dt.valsC != nil {
- return dt.valsC, nil
+ dt.valsC.Close()
+ dt.valsC = nil
}
if dt.d.largeValues {
diff --git a/erigon-lib/state/domain_shared.go b/erigon-lib/state/domain_shared.go
index 6e0793a3966..abd5ee0177a 100644
--- a/erigon-lib/state/domain_shared.go
+++ b/erigon-lib/state/domain_shared.go
@@ -1294,6 +1294,10 @@ func (sdc *SharedDomainsCommitmentContext) KeysCount() uint64 {
return sdc.updates.Size()
}
+func (sdc *SharedDomainsCommitmentContext) Trie() commitment.Trie {
+ return sdc.patriciaTrie
+}
+
// TouchPlainKey marks plainKey as updated and applies different fn for different key types
// (different behaviour for Code, Account and Storage key modifications).
func (sdc *SharedDomainsCommitmentContext) TouchKey(d kv.Domain, key string, val []byte) {
diff --git a/erigon-lib/state/history.go b/erigon-lib/state/history.go
index 78ddeb764c2..13728088c3f 100644
--- a/erigon-lib/state/history.go
+++ b/erigon-lib/state/history.go
@@ -1079,7 +1079,7 @@ func (ht *HistoryRoTx) Prune(ctx context.Context, rwTx kv.RwTx, txFrom, txTo, li
}
if ht.h.historyLargeValues {
- seek = append(append(seek[:0], k...), txnm...)
+ seek = append(bytes.Clone(k), txnm...)
if err := valsC.Delete(seek); err != nil {
return err
}
diff --git a/erigon-lib/trie/debug.go b/erigon-lib/trie/debug.go
index ecc340338c6..85ffa48917c 100644
--- a/erigon-lib/trie/debug.go
+++ b/erigon-lib/trie/debug.go
@@ -37,11 +37,28 @@ func (*HexStdOutWriter) Write(p []byte) (n int, err error) {
return len(p), nil
}
+func (t *Trie) Print(w io.Writer) {
+ witness, err := t.ExtractWitness(false, nil)
+ if err != nil {
+ panic(err)
+ }
+ _, err = witness.WriteInto(w)
+ if err != nil {
+ panic(err)
+ }
+}
+
+func (t *Trie) PrintTrie() {
+ fmt.Printf("trie:0x")
+ t.Print(&HexStdOutWriter{})
+ fmt.Println("")
+}
+
func (t *Trie) PrintDiff(t2 *Trie, w io.Writer) {
- printDiff(t.root, t2.root, w, "", "0x")
+ printDiff(t.RootNode, t2.RootNode, w, "", "0x")
}
-func (n *fullNode) fstring(ind string) string {
+func (n *FullNode) fstring(ind string) string {
resp := fmt.Sprintf("full\n%s ", ind)
for i, node := range &n.Children {
if node == nil {
@@ -52,7 +69,7 @@ func (n *fullNode) fstring(ind string) string {
}
return resp + "\n" + ind + "]"
}
-func (n *fullNode) print(w io.Writer) {
+func (n *FullNode) print(w io.Writer) {
fmt.Fprintf(w, "f(")
for i, node := range &n.Children {
if node != nil {
@@ -63,14 +80,14 @@ func (n *fullNode) print(w io.Writer) {
fmt.Fprintf(w, ")")
}
-func (n *duoNode) fstring(ind string) string {
+func (n *DuoNode) fstring(ind string) string {
resp := fmt.Sprintf("duo[\n%s ", ind)
i1, i2 := n.childrenIdx()
resp += fmt.Sprintf("%s: %v", indices[i1], n.child1.fstring(ind+" "))
resp += fmt.Sprintf("%s: %v", indices[i2], n.child2.fstring(ind+" "))
return resp + fmt.Sprintf("\n%s] ", ind)
}
-func (n *duoNode) print(w io.Writer) {
+func (n *DuoNode) print(w io.Writer) {
fmt.Fprintf(w, "d(")
i1, i2 := n.childrenIdx()
fmt.Fprintf(w, "%d:", i1)
@@ -80,55 +97,55 @@ func (n *duoNode) print(w io.Writer) {
fmt.Fprintf(w, ")")
}
-func (n *shortNode) fstring(ind string) string {
+func (n *ShortNode) fstring(ind string) string {
return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" "))
}
-func (n *shortNode) print(w io.Writer) {
+func (n *ShortNode) print(w io.Writer) {
fmt.Fprintf(w, "s(%x:", n.Key)
n.Val.print(w)
fmt.Fprintf(w, ")")
}
-func (n hashNode) fstring(ind string) string {
+func (n HashNode) fstring(ind string) string {
return fmt.Sprintf("<%x> ", n.hash)
}
-func (n hashNode) print(w io.Writer) {
+func (n HashNode) print(w io.Writer) {
fmt.Fprintf(w, "h(%x)", n.hash)
}
-func (n valueNode) fstring(ind string) string {
+func (n ValueNode) fstring(ind string) string {
return fmt.Sprintf("%x ", []byte(n))
}
-func (n valueNode) print(w io.Writer) {
+func (n ValueNode) print(w io.Writer) {
fmt.Fprintf(w, "v(%x)", []byte(n))
}
-func (n codeNode) fstring(ind string) string {
+func (n CodeNode) fstring(ind string) string {
return fmt.Sprintf("code: %x ", []byte(n))
}
-func (n codeNode) print(w io.Writer) {
+func (n CodeNode) print(w io.Writer) {
fmt.Fprintf(w, "code(%x)", []byte(n))
}
-func (an accountNode) fstring(ind string) string {
+func (an AccountNode) fstring(ind string) string {
encodedAccount := make([]byte, an.EncodingLengthForHashing())
an.EncodeForHashing(encodedAccount)
- if an.storage == nil {
+ if an.Storage == nil {
return hex.EncodeToString(encodedAccount)
}
- return hex.EncodeToString(encodedAccount) + " " + an.storage.fstring(ind+" ")
+ return hex.EncodeToString(encodedAccount) + " " + an.Storage.fstring(ind+" ")
}
-func (an accountNode) print(w io.Writer) {
+func (an AccountNode) print(w io.Writer) {
encodedAccount := make([]byte, an.EncodingLengthForHashing())
an.EncodeForHashing(encodedAccount)
fmt.Fprintf(w, "v(%x)", encodedAccount)
}
-func printDiffSide(n node, w io.Writer, ind string, key string) {
+func printDiffSide(n Node, w io.Writer, ind string, key string) {
switch n := n.(type) {
- case *fullNode:
+ case *FullNode:
fmt.Fprintf(w, "full(\n")
for i, child := range &n.Children {
if child != nil {
@@ -138,7 +155,7 @@ func printDiffSide(n node, w io.Writer, ind string, key string) {
}
}
fmt.Fprintf(w, "%s)\n", ind)
- case *duoNode:
+ case *DuoNode:
fmt.Fprintf(w, "duo(\n")
i1, i2 := n.childrenIdx()
fmt.Fprintf(w, "%s%s:", ind, indices[i1])
@@ -148,7 +165,7 @@ func printDiffSide(n node, w io.Writer, ind string, key string) {
printDiffSide(n.child2, w, " "+ind, key+indices[i2])
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "%s)\n", ind)
- case *shortNode:
+ case *ShortNode:
fmt.Fprintf(w, "short %x(", n.reference())
keyHex := n.Key
hexV := make([]byte, len(keyHex))
@@ -159,19 +176,19 @@ func printDiffSide(n node, w io.Writer, ind string, key string) {
printDiffSide(n.Val, w, " "+ind, key+string(hexV))
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "%s)\n", ind)
- case hashNode:
+ case HashNode:
fmt.Fprintf(w, "hash(%x)", n.hash)
- case valueNode:
+ case ValueNode:
fmt.Fprintf(w, "value(%s %x)", key, []byte(n))
- case *accountNode:
+ case *AccountNode:
fmt.Fprintf(w, "account(%s %x)", key, n)
}
}
-func printDiff(n1, n2 node, w io.Writer, ind string, key string) {
- if nv1, ok := n1.(valueNode); ok {
+func printDiff(n1, n2 Node, w io.Writer, ind string, key string) {
+ if nv1, ok := n1.(ValueNode); ok {
fmt.Fprintf(w, "value(")
- if n, ok := n2.(valueNode); ok {
+ if n, ok := n2.(ValueNode); ok {
fmt.Fprintf(w, "%s %x/%x", key, []byte(nv1), []byte(n))
} else {
fmt.Fprintf(w, "/%T", n2)
@@ -187,9 +204,9 @@ func printDiff(n1, n2 node, w io.Writer, ind string, key string) {
return
}
switch n1 := n1.(type) {
- case *fullNode:
+ case *FullNode:
fmt.Fprintf(w, "full(\n")
- if n, ok := n2.(*fullNode); ok {
+ if n, ok := n2.(*FullNode); ok {
for i, child := range &n1.Children {
child2 := n.Children[i]
if child == nil {
@@ -211,9 +228,9 @@ func printDiff(n1, n2 node, w io.Writer, ind string, key string) {
printDiffSide(n2, w, ind, key)
}
fmt.Fprintf(w, "%s)\n", ind)
- case *duoNode:
+ case *DuoNode:
fmt.Fprintf(w, "duo(\n")
- if n, ok := n2.(*duoNode); ok {
+ if n, ok := n2.(*DuoNode); ok {
i1, i2 := n1.childrenIdx()
j1, j2 := n.childrenIdx()
if i1 == j1 {
@@ -235,9 +252,9 @@ func printDiff(n1, n2 node, w io.Writer, ind string, key string) {
printDiffSide(n1, w, ind, key)
}
fmt.Fprintf(w, "%s)\n", ind)
- case *shortNode:
+ case *ShortNode:
fmt.Fprintf(w, "short(")
- if n, ok := n2.(*shortNode); ok {
+ if n, ok := n2.(*ShortNode); ok {
if bytes.Equal(n1.Key, n.Key) {
keyHex := n1.Key
hexV := make([]byte, len(keyHex))
@@ -260,9 +277,9 @@ func printDiff(n1, n2 node, w io.Writer, ind string, key string) {
printDiffSide(n2, w, ind, key)
}
fmt.Fprintf(w, "%s)\n", ind)
- case hashNode:
+ case HashNode:
fmt.Fprintf(w, "hash(")
- if n, ok := n2.(hashNode); ok {
+ if n, ok := n2.(HashNode); ok {
fmt.Fprintf(w, "%x/%x", n1.hash, n.hash)
} else {
fmt.Fprintf(w, "hash(%x)/%T(%x)\n", n1.hash, n2, n2.reference())
@@ -273,25 +290,25 @@ func printDiff(n1, n2 node, w io.Writer, ind string, key string) {
}
func (t *Trie) HashOfHexKey(hexKey []byte) (libcommon.Hash, error) {
- nd := t.root
+ nd := t.RootNode
pos := 0
var account bool
for pos < len(hexKey) || account {
switch n := nd.(type) {
case nil:
return libcommon.Hash{}, fmt.Errorf("premature nil: pos %d, hexKey %x", pos, hexKey)
- case *shortNode:
+ case *ShortNode:
matchlen := prefixLen(hexKey[pos:], n.Key)
if matchlen == len(n.Key) || n.Key[matchlen] == 16 {
nd = n.Val
pos += matchlen
- if _, ok := n.Val.(*accountNode); ok {
+ if _, ok := n.Val.(*AccountNode); ok {
account = true
}
} else {
return libcommon.Hash{}, fmt.Errorf("too long shortNode key: pos %d, hexKey %x: %s", pos, hexKey, n.fstring(""))
}
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
switch hexKey[pos] {
case i1:
@@ -303,26 +320,26 @@ func (t *Trie) HashOfHexKey(hexKey []byte) (libcommon.Hash, error) {
default:
return libcommon.Hash{}, fmt.Errorf("nil entry in the duoNode: pos %d, hexKey %x", pos, hexKey)
}
- case *fullNode:
+ case *FullNode:
child := n.Children[hexKey[pos]]
if child == nil {
return libcommon.Hash{}, fmt.Errorf("nil entry in the fullNode: pos %d, hexKey %x", pos, hexKey)
}
nd = child
pos++
- case valueNode:
+ case ValueNode:
return libcommon.Hash{}, fmt.Errorf("premature valueNode: pos %d, hexKey %x", pos, hexKey)
- case *accountNode:
- nd = n.storage
+ case *AccountNode:
+ nd = n.Storage
account = false
- case hashNode:
+ case HashNode:
return libcommon.Hash{}, fmt.Errorf("premature hashNode: pos %d, hexKey %x", pos, hexKey)
default:
panic(fmt.Sprintf("Unknown node: %T", n))
}
}
var hash libcommon.Hash
- if hn, ok := nd.(hashNode); ok {
+ if hn, ok := nd.(HashNode); ok {
copy(hash[:], hn.hash)
} else {
h := t.newHasherFunc()
diff --git a/erigon-lib/trie/hack.go b/erigon-lib/trie/hack.go
index 17ab3ebc308..6eb67eb4470 100644
--- a/erigon-lib/trie/hack.go
+++ b/erigon-lib/trie/hack.go
@@ -24,7 +24,7 @@ import (
)
func FullNode1() {
- f := &fullNode{}
+ f := &FullNode{}
b, err := rlp.EncodeToBytes(f)
if err != nil {
panic(err)
@@ -33,8 +33,8 @@ func FullNode1() {
}
func FullNode2() {
- f := &fullNode{}
- f.Children[0] = valueNode(nil)
+ f := &FullNode{}
+ f.Children[0] = ValueNode(nil)
b, err := rlp.EncodeToBytes(f)
if err != nil {
panic(err)
@@ -43,10 +43,10 @@ func FullNode2() {
}
func FullNode3() {
- f := &fullNode{}
- f.Children[0] = valueNode(nil)
+ f := &FullNode{}
+ f.Children[0] = ValueNode(nil)
h := common.Hash{}
- f.Children[1] = hashNode{hash: h[:]}
+ f.Children[1] = HashNode{hash: h[:]}
b, err := rlp.EncodeToBytes(f)
if err != nil {
panic(err)
@@ -55,10 +55,10 @@ func FullNode3() {
}
func FullNode4() {
- f := &fullNode{}
+ f := &FullNode{}
h := common.Hash{}
for i := 0; i < 17; i++ {
- f.Children[i] = hashNode{hash: h[:]}
+ f.Children[i] = HashNode{hash: h[:]}
}
b, err := rlp.EncodeToBytes(f)
if err != nil {
@@ -68,7 +68,7 @@ func FullNode4() {
}
func ShortNode1() {
- s := NewShortNode([]byte("1"), valueNode("2"))
+ s := NewShortNode([]byte("1"), ValueNode("2"))
b, err := rlp.EncodeToBytes(s)
if err != nil {
panic(err)
@@ -77,7 +77,7 @@ func ShortNode1() {
}
func ShortNode2() {
- s := NewShortNode([]byte("1"), valueNode("123456789012345678901234567890123456789012345678901234567890"))
+ s := NewShortNode([]byte("1"), ValueNode("123456789012345678901234567890123456789012345678901234567890"))
b, err := rlp.EncodeToBytes(s)
if err != nil {
panic(err)
@@ -85,7 +85,7 @@ func ShortNode2() {
fmt.Printf("ShortNode2 %x\n", b)
}
-func hashRoot(n node, title string) {
+func hashRoot(n Node, title string) {
h := newHasher(false)
h1 := newHasher(true)
defer returnHasherToPool(h)
@@ -93,51 +93,51 @@ func hashRoot(n node, title string) {
var hash common.Hash
hLen, _ := h.hash(n, true, hash[:])
if hLen < 32 {
- panic("expected hashNode")
+ panic("expected HashNode")
}
fmt.Printf("%s noencode: %x\n", title, hash[:])
hLen, _ = h1.hash(n, true, hash[:])
if hLen < 32 {
- panic("expected hashNode")
+ panic("expected HashNode")
}
fmt.Printf("%s encode: %x\n", title, hash[:])
}
func Hash1() {
- f := &fullNode{}
+ f := &FullNode{}
hashRoot(f, "Hash1")
}
func Hash2() {
- f := &fullNode{}
- f.Children[0] = &fullNode{}
+ f := &FullNode{}
+ f.Children[0] = &FullNode{}
hashRoot(f, "Hash2")
}
func Hash3() {
- s := NewShortNode([]byte("12"), valueNode("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"))
+ s := NewShortNode([]byte("12"), ValueNode("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"))
hashRoot(s, "Hash3")
}
func Hash4() {
- s := NewShortNode([]byte("12345678901234567890123456789012"), valueNode("12345678901234567890"))
+ s := NewShortNode([]byte("12345678901234567890123456789012"), ValueNode("12345678901234567890"))
hashRoot(s, "Hash4")
}
func Hash5() {
- s := NewShortNode([]byte("1234567890123456789012345678901"), valueNode("1"))
+ s := NewShortNode([]byte("1234567890123456789012345678901"), ValueNode("1"))
hashRoot(s, "Hash5")
}
func Hash6() {
- s := NewShortNode(common.FromHex("080010"), valueNode(common.FromHex("f90129a0bc7bbe9ce39e604900ca736606290650c4c630501a97745a3f21fae5261623df830362c0b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0")))
+ s := NewShortNode(common.FromHex("080010"), ValueNode(common.FromHex("f90129a0bc7bbe9ce39e604900ca736606290650c4c630501a97745a3f21fae5261623df830362c0b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0")))
hashRoot(s, "Hash6")
}
func Hash7() {
- d := &duoNode{}
- d.child1 = NewShortNode(common.FromHex("0110"), valueNode(common.FromHex("f871820ba5850ba43b7400830186a0942eb08efb9e10d9f56e46938f28c13ecb33f67b158a085c1bad4187cfe90000801ba0a7e45cf38e44d2c39a4b94bae2e14fccde41e3280c57b611d9cb6494fde12fc7a00858adac2ba2381c591978b8404c22981f7141f0aef9c3cab8f93a55efc40acc")))
- d.child2 = NewShortNode(common.FromHex("0010"), valueNode(common.FromHex("fa02368e820276850ba43b7400830f4240947fd85d1fc04087b3d9d1e610410989191c09b97380ba023624847b07e7000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000011af74000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000008b0000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000ae0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000ab0000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000830000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000008b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000b10000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000a60000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000dd000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000d50000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000f30000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000970000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000c700000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000a30000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000005d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000009b0000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000a5000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000970000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000f50000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000f50000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008c00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000c90000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000ce0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000490000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000680000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000b40000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000f6000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000da0000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000f10000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000bf0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000db0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000430000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000490000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000c50000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000e70000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000007500000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000910000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000a60000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000071000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000810000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000c50000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000eb0000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000b60000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000c700000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000bd0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000dd0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000003f0000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000b60000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009f0000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000d3000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000009d0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000e7000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000d70000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008c00000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000b30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000830000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000b5000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000ce0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000007500000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a30000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000c60000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000f8000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000008f0000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000af0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000830000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000d9000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000009d0000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000ef0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000b10000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000be0000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000008c00000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000f8000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000a60000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000000000a5000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000f20000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000ed0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000a50000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000009e0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000001d0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000e3000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000ec0000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000e7000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000e200000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000ab0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000d5000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000005b0000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000fe0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000870000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000006200000000000000000000000000000000000000000000000000000000000000af0000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000005b0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000b80000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000c70000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000c50000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000007c0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000006b00000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000e7000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000ac0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000009b0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000a90000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000f6000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000d2000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000c90000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000c700000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000a80000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000d50000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000a10000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000d2000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000e70000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000c60000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000970000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000009c0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000e600000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000df0000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000d10000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000ec0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000009e0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000cf00000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f6000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000d3000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000cc0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000b50000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000cb0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000d8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000fc0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d2000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000eb000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000008c0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000a80000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000dc000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000009f0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000005b0000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000a20000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000de00000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000071000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000e20000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000a70000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000005d00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000f70000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000fb0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000cf00000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000df0000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000f40000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000dc000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000c20000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000006b00000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000fc0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000bd0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000d5000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000b5000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000071000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000ac0000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000009c0000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000bf0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000e20000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000cf00000000000000000000000000000000000000000000000000000000000000cf0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000d8000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000a70000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000008e000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c20000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000a40000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000b40000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000004d0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000f70000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000cc0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000c70000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000bd0000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000005e0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000490000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000d8000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e3000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000a40000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000006200000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f70000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000c70000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000b60000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000a20000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000c20000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000d9000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000d10000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000d70000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000510000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000008f0000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000de00000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000df0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000d9000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000a30000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000960000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d10000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000e3000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000eb000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000d70000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000006b00000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000f60000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000003f0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000005d00000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000ae0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000ce0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000ab0000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000001ba05d4d29b6f1b101809f9b43edea6e227828ed7df55663b482cff3d9d7a14ec20aa023db82ed86dd399e73aee94f0f0f8854d352c413e64c4b7f8d8a9bf5cb198d4b")))
+ d := &DuoNode{}
+ d.child1 = NewShortNode(common.FromHex("0110"), ValueNode(common.FromHex("f871820ba5850ba43b7400830186a0942eb08efb9e10d9f56e46938f28c13ecb33f67b158a085c1bad4187cfe90000801ba0a7e45cf38e44d2c39a4b94bae2e14fccde41e3280c57b611d9cb6494fde12fc7a00858adac2ba2381c591978b8404c22981f7141f0aef9c3cab8f93a55efc40acc")))
+ d.child2 = NewShortNode(common.FromHex("0010"), ValueNode(common.FromHex("fa02368e820276850ba43b7400830f4240947fd85d1fc04087b3d9d1e610410989191c09b97380ba023624847b07e7000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000011af74000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000008b0000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000ae0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000ab0000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000830000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000008b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000b10000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000a60000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000dd000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000d50000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000f30000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000970000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000c700000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000a30000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000005d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000009b0000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000a5000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000970000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000f50000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000f50000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008c00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000c90000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000ce0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000490000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000680000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000b40000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000f6000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000da0000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000f10000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000bf0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000db0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000430000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000490000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000c50000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000e70000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000007500000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000910000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000a60000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000071000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000810000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000c50000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000eb0000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000b60000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000c700000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000bd0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000dd0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000003f0000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000b60000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009f0000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000d3000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000009d0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000e7000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000d70000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008c00000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000b30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000830000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000b5000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000ce0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000007500000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000730000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a30000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000c60000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000f8000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000008f0000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000af0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000830000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000d9000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000009d0000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000ef0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000b10000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000be0000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000008c00000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000f8000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000a60000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000000000a5000000000000000000000000000000000000000000000000000000000000005d0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000f20000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000ed0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000a50000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000009e0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000001d0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000e3000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000ec0000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000e7000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000e200000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000ab0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000d5000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000005b0000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000fe0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000870000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000006200000000000000000000000000000000000000000000000000000000000000af0000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000005b0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000b80000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000c70000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000c50000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000007c0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000006b00000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000e7000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000009d00000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000ac0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000009b0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000a90000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000f6000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000d2000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000c90000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000c700000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000a80000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000d50000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000a10000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000d2000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000e70000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000c60000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000970000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000009c0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000e600000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000df0000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000d10000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000ec0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000008b00000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000009e0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000cf00000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f6000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000002f00000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000d3000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000006900000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000cc0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000b50000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000cb0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000d8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000fc0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d2000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000eb000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000008c0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000a80000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000dc000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000009f0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000008d00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000047000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000005b0000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002d0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000a20000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000007200000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000de00000000000000000000000000000000000000000000000000000000000000e4000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000071000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000e20000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000a70000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000005d00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000f70000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000fb0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000cf00000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000002b0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000df0000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000f40000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000cd000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000dc000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000bb000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000007900000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000c20000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000006b00000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000de0000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000fc0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000bd0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000d5000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000e90000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000b5000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000cc000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000071000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000ac0000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000009c0000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000bf0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000ef000000000000000000000000000000000000000000000000000000000000005b00000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000e20000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000cf00000000000000000000000000000000000000000000000000000000000000cf0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000d8000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000a70000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000008e000000000000000000000000000000000000000000000000000000000000005200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c20000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000a40000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000b40000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000004d0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000f70000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000087000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000cc0000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000057000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000c70000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000bd0000000000000000000000000000000000000000000000000000000000000062000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000005e0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000490000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000d8000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e3000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000e50000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000bf000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000a40000000000000000000000000000000000000000000000000000000000000017000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000007a0000000000000000000000000000000000000000000000000000000000000045000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000009500000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000d90000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000006200000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000008e00000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f70000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000f1000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000f2000000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000c70000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c3000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000f4000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000004f000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000b60000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000fe00000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000a20000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000005e00000000000000000000000000000000000000000000000000000000000000fc000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000fe000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000c20000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000e2000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000c9000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000af000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000d7000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000d9000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000d10000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000d70000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000930000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000510000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000007a00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000008f0000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000de00000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000df0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000f7000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000fd000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000007600000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005300000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000d9000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000a30000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000ec000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000097000000000000000000000000000000000000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000960000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000d10000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000e3000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000cf000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000ed000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000eb000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000d70000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000f80000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000a1000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000005800000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000ee000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000006b00000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000f60000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000f5000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000003f0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000005d00000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000ae0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000d60000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000b9000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000ce0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000ab0000000000000000000000000000000000000000000000000000000000000075000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000004900000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000001ba05d4d29b6f1b101809f9b43edea6e227828ed7df55663b482cff3d9d7a14ec20aa023db82ed86dd399e73aee94f0f0f8854d352c413e64c4b7f8d8a9bf5cb198d4b")))
d.mask |= uint32(1) << 0
d.mask |= uint32(1) << 8
hashRoot(d, "Hash7")
diff --git a/erigon-lib/trie/hashbuilder.go b/erigon-lib/trie/hashbuilder.go
index a38d922aade..e982b133345 100644
--- a/erigon-lib/trie/hashbuilder.go
+++ b/erigon-lib/trie/hashbuilder.go
@@ -46,7 +46,7 @@ type HashBuilder struct {
byteArrayWriter *ByteArrayWriter
hashStack []byte // Stack of sub-slices, each 33 bytes each, containing RLP encodings of node hashes (or of nodes themselves, if shorter than 32 bytes)
- nodeStack []node // Stack of nodes
+ nodeStack []Node // Stack of nodes
acc accounts.Account // Working account instance (to avoid extra allocations)
sha keccakState // Keccak primitive that can absorb data (Write), and get squeezed to the hash out (Read)
hashBuf [hashStackStride]byte // RLP representation of hash (or un-hashes value)
@@ -104,7 +104,7 @@ func (hb *HashBuilder) leaf(length int, keyHex []byte, val rlphacks.RlpSerializa
hb.proofElement.storageValue = new(uint256.Int).SetBytes(val.RawBytes())
}
key := keyHex[len(keyHex)-length:]
- s := &shortNode{Key: libcommon.CopyBytes(key), Val: valueNode(libcommon.CopyBytes(val.RawBytes()))}
+ s := &ShortNode{Key: libcommon.CopyBytes(key), Val: ValueNode(libcommon.CopyBytes(val.RawBytes()))}
hb.nodeStack = append(hb.nodeStack, s)
if err := hb.leafHashWithKeyVal(key, val); err != nil {
return err
@@ -245,19 +245,19 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I
hb.acc.Incarnation = incarnation
popped := 0
- var root node
+ var root Node
if fieldSet&uint32(4) != 0 {
copy(hb.acc.Root[:], hb.hashStack[len(hb.hashStack)-popped*hashStackStride-length2.Hash:len(hb.hashStack)-popped*hashStackStride])
if hb.acc.Root != EmptyRoot {
// Root is on top of the stack
root = hb.nodeStack[len(hb.nodeStack)-popped-1]
if root == nil {
- root = hashNode{hash: libcommon.CopyBytes(hb.acc.Root[:])}
+ root = &HashNode{hash: libcommon.CopyBytes(hb.acc.Root[:])}
}
}
popped++
}
- var accountCode codeNode
+ var accountCode CodeNode
if fieldSet&uint32(8) != 0 {
copy(hb.acc.CodeHash[:], hb.hashStack[len(hb.hashStack)-popped*hashStackStride-length2.Hash:len(hb.hashStack)-popped*hashStackStride])
var ok bool
@@ -265,7 +265,7 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I
stackTop := hb.nodeStack[len(hb.nodeStack)-popped-1]
if stackTop != nil { // if we don't have any stack top it might be okay because we didn't resolve the code yet (stateful resolver)
// but if we have something on top of the stack that isn't `nil`, it has to be a codeNode
- accountCode, ok = stackTop.(codeNode)
+ accountCode, ok = stackTop.(CodeNode)
if !ok {
return fmt.Errorf("unexpected node type on the node stack, wanted codeNode, got %T:%s", stackTop, stackTop)
}
@@ -289,8 +289,8 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I
accountCodeSize = len(accountCode)
}
- a := &accountNode{accCopy, root, true, accountCode, accountCodeSize}
- s := &shortNode{Key: libcommon.CopyBytes(key), Val: a}
+ a := &AccountNode{accCopy, root, true, accountCode, accountCodeSize}
+ s := &ShortNode{Key: libcommon.CopyBytes(key), Val: a}
// this invocation will take care of the popping given number of items from both hash stack and node stack,
// pushing resulting hash to the hash stack, and nil to the node stack
if err = hb.accountLeafHashWithKey(key, popped); err != nil {
@@ -391,13 +391,13 @@ func (hb *HashBuilder) extension(key []byte) error {
fmt.Printf("EXTENSION %x\n", key)
}
nd := hb.nodeStack[len(hb.nodeStack)-1]
- var s *shortNode
+ var s *ShortNode
switch n := nd.(type) {
case nil:
branchHash := libcommon.CopyBytes(hb.hashStack[len(hb.hashStack)-length2.Hash:])
- s = &shortNode{Key: libcommon.CopyBytes(key), Val: hashNode{hash: branchHash}}
- case *fullNode:
- s = &shortNode{Key: libcommon.CopyBytes(key), Val: n}
+ s = &ShortNode{Key: libcommon.CopyBytes(key), Val: &HashNode{hash: branchHash}}
+ case *FullNode:
+ s = &ShortNode{Key: libcommon.CopyBytes(key), Val: n}
default:
return fmt.Errorf("wrong Val type for an extension: %T", nd)
}
@@ -488,7 +488,7 @@ func (hb *HashBuilder) extensionHash(key []byte) error {
if hb.trace {
fmt.Printf("extensionHash [%x]=>[%x]\nHash [%x]\n", key, capture, hb.hashStack[len(hb.hashStack)-hashStackStride:len(hb.hashStack)])
}
- if _, ok := hb.nodeStack[len(hb.nodeStack)-1].(*fullNode); ok {
+ if _, ok := hb.nodeStack[len(hb.nodeStack)-1].(*FullNode); ok {
return errors.New("extensionHash cannot be emitted when a node is on top of the stack")
}
return nil
@@ -501,7 +501,7 @@ func (hb *HashBuilder) branch(set uint16) error {
if hb.trace {
fmt.Printf("Stack depth: %d\n", len(hb.nodeStack))
}
- f := &fullNode{}
+ f := &FullNode{}
digits := bits.OnesCount16(set)
if len(hb.nodeStack) < digits {
return fmt.Errorf("len(hb.nodeStask) %d < digits %d", len(hb.nodeStack), digits)
@@ -512,7 +512,7 @@ func (hb *HashBuilder) branch(set uint16) error {
for digit := uint(0); digit < 16; digit++ {
if ((1 << digit) & set) != 0 {
if nodes[i] == nil {
- f.Children[digit] = hashNode{hash: libcommon.CopyBytes(hashes[hashStackStride*i+1 : hashStackStride*(i+1)])}
+ f.Children[digit] = &HashNode{hash: libcommon.CopyBytes(hashes[hashStackStride*i+1 : hashStackStride*(i+1)])}
} else {
f.Children[digit] = nodes[i]
}
@@ -643,7 +643,7 @@ func (hb *HashBuilder) code(code []byte) error {
fmt.Printf("CODE\n")
}
codeCopy := libcommon.CopyBytes(code)
- n := codeNode(codeCopy)
+ n := CodeNode(codeCopy)
hb.nodeStack = append(hb.nodeStack, n)
hb.sha.Reset()
if _, err := hb.sha.Write(codeCopy); err != nil {
@@ -658,6 +658,17 @@ func (hb *HashBuilder) code(code []byte) error {
return nil
}
+func (hb *HashBuilder) emptyRoot() {
+ if hb.trace {
+ fmt.Printf("EMPTYROOT\n")
+ }
+ hb.nodeStack = append(hb.nodeStack, nil)
+ var hash [hashStackStride]byte // RLP representation of hash (or un-hashes value)
+ hash[0] = 0x80 + length2.Hash
+ copy(hash[1:], EmptyRoot[:])
+ hb.hashStack = append(hb.hashStack, hash[:]...)
+}
+
func (hb *HashBuilder) RootHash() (libcommon.Hash, error) {
if !hb.hasRoot() {
return libcommon.Hash{}, errors.New("no root in the tree")
@@ -721,7 +732,7 @@ func (hb *HashBuilder) topHashes(prefix []byte, hasHash, hasState uint16) []byte
return hb.topHashesCopy
}
-func (hb *HashBuilder) root() node {
+func (hb *HashBuilder) root() Node {
if hb.trace && len(hb.nodeStack) > 0 {
fmt.Printf("len(hb.nodeStack)=%d\n", len(hb.nodeStack))
}
diff --git a/erigon-lib/trie/hasher.go b/erigon-lib/trie/hasher.go
index e191ca32044..5a11bc38318 100644
--- a/erigon-lib/trie/hasher.go
+++ b/erigon-lib/trie/hasher.go
@@ -21,15 +21,15 @@ package trie
import (
"errors"
+ "fmt"
"hash"
"sync"
- "golang.org/x/crypto/sha3"
-
libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/length"
- "github.com/erigontech/erigon-lib/crypto"
+ "golang.org/x/crypto/sha3"
+ "github.com/erigontech/erigon-lib/crypto"
"github.com/erigontech/erigon-lib/rlp"
"github.com/erigontech/erigon-lib/rlphacks"
)
@@ -40,7 +40,7 @@ type hasher struct {
buffers [1024 * 1024]byte
prefixBuf [8]byte
bw *ByteArrayWriter
- callback func(libcommon.Hash, node)
+ callback func(libcommon.Hash, Node)
}
const rlpPrefixLength = 4
@@ -76,7 +76,7 @@ func returnHasherToPool(h *hasher) {
// and stores the RLP if len(RLP) < 32 and not force,
// otherwise it stores hash(RLP).
// It also updates node's ref with that value.
-func (h *hasher) hash(n node, force bool, storeTo []byte) (int, error) {
+func (h *hasher) hash(n Node, force bool, storeTo []byte) (int, error) {
return h.hashInternal(n, force, storeTo, 0)
}
@@ -84,8 +84,8 @@ func (h *hasher) hash(n node, force bool, storeTo []byte) (int, error) {
// and stores the RLP if len(RLP) < 32 and not force,
// otherwise it stores hash(RLP).
// It also updates node's ref with that value.
-func (h *hasher) hashInternal(n node, force bool, storeTo []byte, bufOffset int) (int, error) {
- if hn, ok := n.(hashNode); ok {
+func (h *hasher) hashInternal(n Node, force bool, storeTo []byte, bufOffset int) (int, error) {
+ if hn, ok := n.(HashNode); ok {
copy(storeTo, hn.hash)
return length.Hash, nil
}
@@ -105,15 +105,15 @@ func (h *hasher) hashInternal(n node, force bool, storeTo []byte, bufOffset int)
}
switch n := n.(type) {
- case *shortNode:
+ case *ShortNode:
copy(n.ref.data[:], storeTo)
n.ref.len = byte(refLen)
- case *accountNode:
- n.rootCorrect = true
- case *duoNode:
+ case *AccountNode:
+ n.RootCorrect = true
+ case *DuoNode:
copy(n.ref.data[:], storeTo)
n.ref.len = byte(refLen)
- case *fullNode:
+ case *FullNode:
copy(n.ref.data[:], storeTo)
n.ref.len = byte(refLen)
}
@@ -155,12 +155,12 @@ func writeRlpPrefix(buffer []byte, pos int) []byte {
// if the RLP-encoded size of the child is >= 32,
// returning node's RLP with the child hashes cached in.
// DESCRIBED: docs/programmers_guide/guide.md#hexary-radix-patricia-tree
-func (h *hasher) hashChildren(original node, bufOffset int) ([]byte, error) {
+func (h *hasher) hashChildren(original Node, bufOffset int) ([]byte, error) {
buffer := h.buffers[bufOffset:]
pos := rlpPrefixLength
switch n := original.(type) {
- case *shortNode:
+ case *ShortNode:
// Starting at position 3, to leave space for len prefix
// Encode key
compactKey := hexToCompact(n.Key)
@@ -172,19 +172,19 @@ func (h *hasher) hashChildren(original node, bufOffset int) ([]byte, error) {
pos += written
// Encode value
- if vn, ok := n.Val.(valueNode); ok {
+ if vn, ok := n.Val.(ValueNode); ok {
written, err := h.valueNodeToBuffer(vn, buffer, pos)
if err != nil {
return nil, err
}
pos += written
- } else if ac, ok := n.Val.(*accountNode); ok {
+ } else if ac, ok := n.Val.(*AccountNode); ok {
// Hashing the storage trie if necessary
- if ac.storage == nil {
+ if ac.Storage == nil {
ac.Root = EmptyRoot
} else {
- _, err := h.hashInternal(ac.storage, true, ac.Root[:], bufOffset+pos)
+ _, err := h.hashInternal(ac.Storage, true, ac.Root[:], bufOffset+pos)
if err != nil {
return nil, err
}
@@ -204,10 +204,10 @@ func (h *hasher) hashChildren(original node, bufOffset int) ([]byte, error) {
}
return writeRlpPrefix(buffer, pos), nil
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
for i := 0; i < 17; i++ {
- var child node
+ var child Node
if i == int(i1) {
child = n.child1
@@ -227,7 +227,7 @@ func (h *hasher) hashChildren(original node, bufOffset int) ([]byte, error) {
}
return writeRlpPrefix(buffer, pos), nil
- case *fullNode:
+ case *FullNode:
// Hash the full node's children, caching the newly hashed subtrees
for _, child := range n.Children[:16] {
written, err := h.hashChild(child, buffer, pos, bufOffset)
@@ -237,14 +237,14 @@ func (h *hasher) hashChildren(original node, bufOffset int) ([]byte, error) {
pos += written
}
switch n := n.Children[16].(type) {
- case *accountNode:
+ case *AccountNode:
written, err := h.accountNodeToBuffer(n, buffer, pos)
if err != nil {
return nil, err
}
pos += written
- case valueNode:
+ case ValueNode:
written, err := h.valueNodeToBuffer(n, buffer, pos)
if err != nil {
return nil, err
@@ -260,7 +260,7 @@ func (h *hasher) hashChildren(original node, bufOffset int) ([]byte, error) {
return writeRlpPrefix(buffer, pos), nil
- case valueNode:
+ case ValueNode:
written, err := h.valueNodeToBuffer(n, buffer, pos)
if err != nil {
return nil, err
@@ -269,19 +269,19 @@ func (h *hasher) hashChildren(original node, bufOffset int) ([]byte, error) {
return buffer[rlpPrefixLength:pos], nil
- case *accountNode:
+ case *AccountNode:
// we don't do double RLP here, so `accountNodeToBuffer` is not applicable
n.EncodeForHashing(buffer[pos:])
return buffer[rlpPrefixLength:pos], nil
- case hashNode:
+ case HashNode:
return nil, errors.New("hasher#hashChildren: met unexpected hash node")
}
return nil, nil
}
-func (h *hasher) valueNodeToBuffer(vn valueNode, buffer []byte, pos int) (int, error) {
+func (h *hasher) valueNodeToBuffer(vn ValueNode, buffer []byte, pos int) (int, error) {
h.bw.Setup(buffer, pos)
var val rlphacks.RlpSerializable
@@ -292,13 +292,14 @@ func (h *hasher) valueNodeToBuffer(vn valueNode, buffer []byte, pos int) (int, e
val = rlphacks.RlpSerializableBytes(vn)
}
+ fmt.Printf("valueNodeToBuffer()>>>>>>> val=%x\n", val)
if err := val.ToDoubleRLP(h.bw, h.prefixBuf[:]); err != nil {
return 0, err
}
return val.DoubleRLPLen(), nil
}
-func (h *hasher) accountNodeToBuffer(ac *accountNode, buffer []byte, pos int) (int, error) {
+func (h *hasher) accountNodeToBuffer(ac *AccountNode, buffer []byte, pos int) (int, error) {
acRlp := make([]byte, ac.EncodingLengthForHashing())
ac.EncodeForHashing(acRlp)
enc := rlphacks.RlpEncodedBytes(acRlp)
@@ -336,7 +337,7 @@ func (h *hasher) nodeRef(nodeRlp []byte, force bool, storeTo []byte) (int, error
return 32, nil
}
-func (h *hasher) hashChild(child node, buffer []byte, pos int, bufOffset int) (int, error) {
+func (h *hasher) hashChild(child Node, buffer []byte, pos int, bufOffset int) (int, error) {
if child == nil {
return writeEmptyByteArray(buffer, pos), nil
}
diff --git a/erigon-lib/trie/hasher_test.go b/erigon-lib/trie/hasher_test.go
index ca1b4d87490..542cd16440c 100644
--- a/erigon-lib/trie/hasher_test.go
+++ b/erigon-lib/trie/hasher_test.go
@@ -28,7 +28,7 @@ func TestValue(t *testing.T) {
h := newHasher(false)
var hn libcommon.Hash
- h.hash(valueNode("BLAH"), false, hn[:])
+ h.hash(ValueNode("BLAH"), false, hn[:])
expected := "0x0"
actual := fmt.Sprintf("0x%x", hn[:])
if actual != expected {
diff --git a/erigon-lib/trie/node.go b/erigon-lib/trie/node.go
index 5fbdfb187df..9900eb0043b 100644
--- a/erigon-lib/trie/node.go
+++ b/erigon-lib/trie/node.go
@@ -34,7 +34,7 @@ const codeSizeUncached = -1
var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"}
-type node interface {
+type Node interface {
print(io.Writer)
fstring(string) string
@@ -44,45 +44,49 @@ type node interface {
type (
// DESCRIBED: docs/programmers_guide/guide.md#hexary-radix-patricia-tree
- fullNode struct {
+ FullNode struct {
ref nodeRef
- Children [17]node // Actual trie node data to encode/decode (needs custom encoder)
+ Children [17]Node // Actual trie node data to encode/decode (needs custom encoder)
}
// DESCRIBED: docs/programmers_guide/guide.md#hexary-radix-patricia-tree
- duoNode struct {
+ DuoNode struct {
ref nodeRef
mask uint32 // Bitmask. The set bits indicate the child is not nil
- child1 node
- child2 node
+ child1 Node
+ child2 Node
}
// DESCRIBED: docs/programmers_guide/guide.md#hexary-radix-patricia-tree
- shortNode struct {
+ ShortNode struct {
ref nodeRef
Key []byte // HEX encoding
- Val node
+ Val Node
}
- hashNode struct {
+ HashNode struct {
hash []byte
}
- valueNode []byte
+ ValueNode []byte
- accountNode struct {
+ AccountNode struct {
accounts.Account
- storage node
- rootCorrect bool
- code codeNode
- codeSize int
+ Storage Node
+ RootCorrect bool
+ Code CodeNode
+ CodeSize int
}
- codeNode []byte
+ CodeNode []byte
)
// nilValueNode is used when collapsing internal trie nodes for hashing, since
// unset hasState need to serialize correctly.
-var nilValueNode = valueNode(nil)
+var nilValueNode = ValueNode(nil)
-func NewShortNode(key []byte, value node) *shortNode {
- s := &shortNode{
+func NewHashNode(hash []byte) *HashNode {
+ return &HashNode{hash: hash}
+}
+
+func NewShortNode(key []byte, value Node) *ShortNode {
+ s := &ShortNode{
Key: key,
Val: value,
}
@@ -92,15 +96,15 @@ func NewShortNode(key []byte, value node) *shortNode {
func EncodeAsValue(data []byte) ([]byte, error) {
tmp := new(bytes.Buffer)
- if err := rlp.Encode(tmp, valueNode(data)); err != nil {
+ if err := rlp.Encode(tmp, ValueNode(data)); err != nil {
return nil, err
}
return tmp.Bytes(), nil
}
// EncodeRLP encodes a full node into the consensus RLP format.
-func (n *fullNode) EncodeRLP(w io.Writer) error {
- var nodes [17]node
+func (n *FullNode) EncodeRLP(w io.Writer) error {
+ var nodes [17]Node
for i, child := range &n.Children {
if child != nil {
@@ -112,20 +116,20 @@ func (n *fullNode) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, nodes)
}
-func (n *duoNode) EncodeRLP(w io.Writer) error {
- var children [17]node
+func (n *DuoNode) EncodeRLP(w io.Writer) error {
+ var children [17]Node
i1, i2 := n.childrenIdx()
children[i1] = n.child1
children[i2] = n.child2
for i := 0; i < 17; i++ {
if i != int(i1) && i != int(i2) {
- children[i] = valueNode(nil)
+ children[i] = ValueNode(nil)
}
}
return rlp.Encode(w, children)
}
-func (n *duoNode) childrenIdx() (i1 byte, i2 byte) {
+func (n *DuoNode) childrenIdx() (i1 byte, i2 byte) {
child := 1
var m uint32 = 1
for i := 0; i < 17; i++ {
@@ -143,16 +147,16 @@ func (n *duoNode) childrenIdx() (i1 byte, i2 byte) {
return i1, i2
}
-func resetRefs(nd node) {
+func resetRefs(nd Node) {
switch n := nd.(type) {
- case *shortNode:
+ case *ShortNode:
n.ref.len = 0
resetRefs(n.Val)
- case *duoNode:
+ case *DuoNode:
n.ref.len = 0
resetRefs(n.child1)
resetRefs(n.child2)
- case *fullNode:
+ case *FullNode:
n.ref.len = 0
for _, child := range n.Children {
if child != nil {
@@ -169,22 +173,22 @@ type nodeRef struct {
len byte // length of the data (0 indicates invalid data)
}
-func (n hashNode) reference() []byte { return n.hash }
-func (n valueNode) reference() []byte { return nil }
-func (n codeNode) reference() []byte { return nil }
-func (n *fullNode) reference() []byte { return n.ref.data[0:n.ref.len] }
-func (n *duoNode) reference() []byte { return n.ref.data[0:n.ref.len] }
-func (n *shortNode) reference() []byte { return n.ref.data[0:n.ref.len] }
-func (an *accountNode) reference() []byte { return nil }
+func (n HashNode) reference() []byte { return n.hash }
+func (n ValueNode) reference() []byte { return nil }
+func (n CodeNode) reference() []byte { return nil }
+func (n *FullNode) reference() []byte { return n.ref.data[0:n.ref.len] }
+func (n *DuoNode) reference() []byte { return n.ref.data[0:n.ref.len] }
+func (n *ShortNode) reference() []byte { return n.ref.data[0:n.ref.len] }
+func (an *AccountNode) reference() []byte { return nil }
// Pretty printing.
-func (n fullNode) String() string { return n.fstring("") }
-func (n duoNode) String() string { return n.fstring("") }
-func (n shortNode) String() string { return n.fstring("") }
-func (n hashNode) String() string { return n.fstring("") }
-func (n valueNode) String() string { return n.fstring("") }
-func (n codeNode) String() string { return n.fstring("") }
-func (an accountNode) String() string { return an.fstring("") }
+func (n FullNode) String() string { return n.fstring("") }
+func (n DuoNode) String() string { return n.fstring("") }
+func (n ShortNode) String() string { return n.fstring("") }
+func (n HashNode) String() string { return n.fstring("") }
+func (n ValueNode) String() string { return n.fstring("") }
+func (n CodeNode) String() string { return n.fstring("") }
+func (an AccountNode) String() string { return an.fstring("") }
func CodeKeyFromAddrHash(addrHash []byte) []byte {
return append(addrHash, 0xC0, 0xDE)
@@ -209,52 +213,52 @@ func AddrHashFromCodeKey(codeKey []byte) []byte {
return codeKey[:len(codeKey)-2]
}
-func calcSubtreeSize(node node) int {
+func calcSubtreeSize(node Node) int {
switch n := node.(type) {
case nil:
return 0
- case valueNode:
+ case ValueNode:
return 0
- case *shortNode:
+ case *ShortNode:
return calcSubtreeSize(n.Val)
- case *duoNode:
+ case *DuoNode:
return 1 + calcSubtreeSize(n.child1) + calcSubtreeSize(n.child2)
- case *fullNode:
+ case *FullNode:
size := 1
for _, child := range n.Children {
size += calcSubtreeSize(child)
}
return size
- case *accountNode:
- return len(n.code) + calcSubtreeSize(n.storage)
- case hashNode:
+ case *AccountNode:
+ return len(n.Code) + calcSubtreeSize(n.Storage)
+ case HashNode:
return 0
}
return 0
}
-func calcSubtreeNodes(node node) int {
+func calcSubtreeNodes(node Node) int {
switch n := node.(type) {
case nil:
return 0
- case valueNode:
+ case ValueNode:
return 0
- case *shortNode:
+ case *ShortNode:
return calcSubtreeNodes(n.Val)
- case *duoNode:
+ case *DuoNode:
return 1 + calcSubtreeNodes(n.child1) + calcSubtreeNodes(n.child2)
- case *fullNode:
+ case *FullNode:
size := 1
for _, child := range n.Children {
size += calcSubtreeNodes(child)
}
return size
- case *accountNode:
- if n.code != nil {
- return 1 + calcSubtreeNodes(n.storage)
+ case *AccountNode:
+ if n.Code != nil {
+ return 1 + calcSubtreeNodes(n.Storage)
}
- return calcSubtreeNodes(n.storage)
- case hashNode:
+ return calcSubtreeNodes(n.Storage)
+ case HashNode:
return 0
}
return 0
diff --git a/erigon-lib/trie/proof.go b/erigon-lib/trie/proof.go
index 9fcd8770aea..6e54235cc18 100644
--- a/erigon-lib/trie/proof.go
+++ b/erigon-lib/trie/proof.go
@@ -43,10 +43,10 @@ func (t *Trie) Prove(key []byte, fromLevel int, storage bool) ([][]byte, error)
// Collect all nodes on the path to key.
key = keybytesToHex(key)
key = key[:len(key)-1] // Remove terminator
- tn := t.root
+ tn := t.RootNode
for len(key) > 0 && tn != nil {
switch n := tn.(type) {
- case *shortNode:
+ case *ShortNode:
if fromLevel == 0 {
if rlp, err := hasher.hashChildren(n, 0); err == nil {
proof = append(proof, libcommon.CopyBytes(rlp))
@@ -68,7 +68,7 @@ func (t *Trie) Prove(key []byte, fromLevel int, storage bool) ([][]byte, error)
if fromLevel > 0 {
fromLevel -= len(nKey)
}
- case *duoNode:
+ case *DuoNode:
if fromLevel == 0 {
if rlp, err := hasher.hashChildren(n, 0); err == nil {
proof = append(proof, libcommon.CopyBytes(rlp))
@@ -90,7 +90,7 @@ func (t *Trie) Prove(key []byte, fromLevel int, storage bool) ([][]byte, error)
if fromLevel > 0 {
fromLevel--
}
- case *fullNode:
+ case *FullNode:
if fromLevel == 0 {
if rlp, err := hasher.hashChildren(n, 0); err == nil {
proof = append(proof, libcommon.CopyBytes(rlp))
@@ -103,15 +103,15 @@ func (t *Trie) Prove(key []byte, fromLevel int, storage bool) ([][]byte, error)
if fromLevel > 0 {
fromLevel--
}
- case *accountNode:
+ case *AccountNode:
if storage {
- tn = n.storage
+ tn = n.Storage
} else {
tn = nil
}
- case valueNode:
+ case ValueNode:
tn = nil
- case hashNode:
+ case HashNode:
return nil, fmt.Errorf("encountered hashNode unexpectedly, key %x, fromLevel %d", key, fromLevel)
default:
panic(fmt.Sprintf("%T: invalid node: %v", tn, tn))
@@ -120,7 +120,7 @@ func (t *Trie) Prove(key []byte, fromLevel int, storage bool) ([][]byte, error)
return proof, nil
}
-func decodeRef(buf []byte) (node, []byte, error) {
+func decodeRef(buf []byte) (Node, []byte, error) {
kind, val, rest, err := rlp.Split(buf)
if err != nil {
return nil, nil, err
@@ -138,14 +138,14 @@ func decodeRef(buf []byte) (node, []byte, error) {
case kind == rlp.String && len(val) == 0:
return nil, rest, nil
case kind == rlp.String && len(val) == 32:
- return hashNode{hash: val}, rest, nil
+ return HashNode{hash: val}, rest, nil
default:
return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 through 32)", len(val))
}
}
-func decodeFull(elems []byte) (*fullNode, error) {
- n := &fullNode{}
+func decodeFull(elems []byte) (*FullNode, error) {
+ n := &FullNode{}
for i := 0; i < 16; i++ {
var err error
n.Children[i], elems, err = decodeRef(elems)
@@ -159,12 +159,12 @@ func decodeFull(elems []byte) (*fullNode, error) {
return nil, err
}
if len(val) > 0 {
- n.Children[16] = valueNode(val)
+ n.Children[16] = ValueNode(val)
}
return n, nil
}
-func decodeShort(elems []byte) (*shortNode, error) {
+func decodeShort(elems []byte) (*ShortNode, error) {
kbuf, rest, err := rlp.SplitString(elems)
if err != nil {
return nil, err
@@ -175,9 +175,9 @@ func decodeShort(elems []byte) (*shortNode, error) {
if err != nil {
return nil, err
}
- return &shortNode{
+ return &ShortNode{
Key: kb.ToHex(),
- Val: valueNode(val),
+ Val: ValueNode(val),
}, nil
}
@@ -185,13 +185,13 @@ func decodeShort(elems []byte) (*shortNode, error) {
if err != nil {
return nil, err
}
- return &shortNode{
+ return &ShortNode{
Key: kb.ToHex(),
Val: val,
}, nil
}
-func decodeNode(encoded []byte) (node, error) {
+func decodeNode(encoded []byte) (Node, error) {
if len(encoded) == 0 {
return nil, errors.New("nodes must not be zero length")
}
@@ -215,8 +215,8 @@ type rawProofElement struct {
}
// proofMap creates a map from hash to proof node
-func proofMap(proof []hexutility.Bytes) (map[libcommon.Hash]node, map[libcommon.Hash]rawProofElement, error) {
- res := map[libcommon.Hash]node{}
+func proofMap(proof []hexutility.Bytes) (map[libcommon.Hash]Node, map[libcommon.Hash]rawProofElement, error) {
+ res := map[libcommon.Hash]Node{}
raw := map[libcommon.Hash]rawProofElement{}
for i, proofB := range proof {
hash := crypto.Keccak256Hash(proofB)
@@ -233,13 +233,13 @@ func proofMap(proof []hexutility.Bytes) (map[libcommon.Hash]node, map[libcommon.
return res, raw, nil
}
-func verifyProof(root libcommon.Hash, key []byte, proofs map[libcommon.Hash]node, used map[libcommon.Hash]rawProofElement) ([]byte, error) {
+func verifyProof(root libcommon.Hash, key []byte, proofs map[libcommon.Hash]Node, used map[libcommon.Hash]rawProofElement) ([]byte, error) {
nextIndex := 0
key = keybytesToHex(key)
- var node node = hashNode{hash: root[:]}
+ var node Node = HashNode{hash: root[:]}
for {
switch nt := node.(type) {
- case *fullNode:
+ case *FullNode:
if len(key) == 0 {
return nil, errors.New("full nodes should not have values")
}
@@ -247,7 +247,7 @@ func verifyProof(root libcommon.Hash, key []byte, proofs map[libcommon.Hash]node
if node == nil {
return nil, nil
}
- case *shortNode:
+ case *ShortNode:
shortHex := nt.Key
if len(shortHex) > len(key) {
return nil, fmt.Errorf("len(shortHex)=%d must be leq len(key)=%d", len(shortHex), len(key))
@@ -256,7 +256,7 @@ func verifyProof(root libcommon.Hash, key []byte, proofs map[libcommon.Hash]node
return nil, nil
}
node, key = nt.Val, key[len(shortHex):]
- case hashNode:
+ case HashNode:
var ok bool
h := libcommon.BytesToHash(nt.hash)
node, ok = proofs[h]
@@ -272,7 +272,7 @@ func verifyProof(root libcommon.Hash, key []byte, proofs map[libcommon.Hash]node
}
nextIndex++
delete(used, h)
- case valueNode:
+ case ValueNode:
if len(key) != 0 {
return nil, fmt.Errorf("value node should have zero length remaining in key %x", key)
}
diff --git a/erigon-lib/trie/retain_list.go b/erigon-lib/trie/retain_list.go
index fb9215c3c4f..e40c3664e65 100644
--- a/erigon-lib/trie/retain_list.go
+++ b/erigon-lib/trie/retain_list.go
@@ -50,11 +50,58 @@ type RetainDeciderWithMarker interface {
RetainWithMarker(prefix []byte) (retain bool, nextMarkedKey []byte)
}
-// ProofRetainer is a wrapper around the RetainList passed to the trie builder.
+// ProofRetainer is an interface that is used to retain proof elements during trie computation
+type ProofRetainer interface {
+ // ProofElement requests a new proof element for a given prefix. Returns nil if
+ // the prefix is not needed for the proof.
+ ProofElement(prefix []byte) *proofElement
+}
+
+type MultiAccountProofRetainer struct {
+ AccHexKeys [][]byte
+ Rl *RetainList
+}
+
+func NewMultiAccountProofRetainer(rl *RetainList) *MultiAccountProofRetainer {
+ return &MultiAccountProofRetainer{
+ AccHexKeys: make([][]byte, 0),
+ Rl: rl,
+ }
+}
+
+func (pr *MultiAccountProofRetainer) ProofElement(prefix []byte) *proofElement {
+ if !pr.Rl.Retain(prefix) && ((len(prefix) > 1) && !pr.Rl.Retain(prefix[:len(prefix)-2])) {
+ return nil
+ }
+
+ found := false
+
+ for _, accHexKey := range pr.AccHexKeys {
+ if bytes.HasPrefix(accHexKey, prefix) {
+ found = true
+ break
+ }
+
+ if bytes.HasPrefix(prefix, accHexKey) {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ return nil
+ }
+
+ return &proofElement{
+ hexKey: prefix,
+ }
+}
+
+// DefaultProofRetainer is a wrapper around the RetainList passed to the trie builder.
// It is responsible for aggregating proof values from the trie computation and
// will return a valid accounts.AccProofresult after the trie root hash
// calculation has completed.
-type ProofRetainer struct {
+type DefaultProofRetainer struct {
rl *RetainList
addr libcommon.Address
acc *accounts.Account
@@ -69,7 +116,7 @@ type ProofRetainer struct {
// storage keys are added to the given RetainList. The ProofRetainer should be
// set onto the FlatDBTrieLoader via SetProofRetainer before performing its Load
// operation in order to appropriately collect the proof elements.
-func NewProofRetainer(addr libcommon.Address, a *accounts.Account, storageKeys []libcommon.Hash, rl *RetainList) (*ProofRetainer, error) {
+func NewProofRetainer(addr libcommon.Address, a *accounts.Account, storageKeys []libcommon.Hash, rl *RetainList) (*DefaultProofRetainer, error) {
addrHash, err := libcommon.HashData(addr[:])
if err != nil {
return nil, err
@@ -90,7 +137,7 @@ func NewProofRetainer(addr libcommon.Address, a *accounts.Account, storageKeys [
storageHexKeys[i] = rl.AddKey(compactEncoded[:])
}
- return &ProofRetainer{
+ return &DefaultProofRetainer{
rl: rl,
addr: addr,
acc: a,
@@ -104,7 +151,7 @@ func NewProofRetainer(addr libcommon.Address, a *accounts.Account, storageKeys [
// element is retained by the ProofRetainer, and will be utilized to compute the
// proof after the trie computation has completed. The prefix is the standard
// nibble encoded prefix used in the rest of the trie computations.
-func (pr *ProofRetainer) ProofElement(prefix []byte) *proofElement {
+func (pr *DefaultProofRetainer) ProofElement(prefix []byte) *proofElement {
if !pr.rl.Retain(prefix) {
return nil
}
@@ -134,7 +181,7 @@ func (pr *ProofRetainer) ProofElement(prefix []byte) *proofElement {
// Balance, Nonce, and CodeHash from the account data supplied in the
// constructor, the StorageHash, storageKey values, and proof elements are
// supplied by the Load operation of the trie construction.
-func (pr *ProofRetainer) ProofResult() (*accounts.AccProofResult, error) {
+func (pr *DefaultProofRetainer) ProofResult() (*accounts.AccProofResult, error) {
result := &accounts.AccProofResult{
Address: pr.addr,
Balance: (*hexutil.Big)(pr.acc.Balance.ToBig()),
@@ -280,6 +327,10 @@ func (rl *RetainList) AddHex(hex []byte) {
rl.hexes = append(rl.hexes, hex)
}
+func (rl *RetainList) AddMarker(marker bool) {
+ rl.markers = append(rl.markers, marker)
+}
+
// AddCodeTouch adds a new code touch into the resolve set
func (rl *RetainList) AddCodeTouch(codeHash libcommon.Hash) {
rl.codeTouches[codeHash] = struct{}{}
@@ -310,6 +361,10 @@ func (rl *RetainList) ensureInited() {
// come in monotonically ascending order, we optimise for this, though
// the function would still work if the order is different
func (rl *RetainList) Retain(prefix []byte) bool {
+ // if bytes.HasPrefix(prefix, libcommon.FromHex("0x0d05")) {
+ // fmt.Println("here!!!!!")
+ // }
+
rl.ensureInited()
if len(prefix) < rl.minLength {
return true
diff --git a/erigon-lib/trie/retain_list_builder.go b/erigon-lib/trie/retain_list_builder.go
new file mode 100644
index 00000000000..adc84d2e2f5
--- /dev/null
+++ b/erigon-lib/trie/retain_list_builder.go
@@ -0,0 +1,101 @@
+package trie
+
+import (
+ "github.com/erigontech/erigon-lib/common"
+)
+
+// RetainListBuilder is the structure that accumulates the list of keys that were read or changes (touched) during
+// the execution of a block. It also tracks the contract codes that were created and used during the execution
+// of a block
+type RetainListBuilder struct {
+ touches [][]byte // Read/change set of account keys (account hashes)
+ storageTouches [][]byte // Read/change set of storage keys (account hashes concatenated with storage key hashes)
+ proofCodes map[common.Hash][]byte // Contract codes that have been accessed (codeHash)
+ createdCodes map[common.Hash]struct{} // Contract codes that were created (deployed) (codeHash)
+}
+
+// NewRetainListBuilder creates new ProofGenerator and initialised its maps
+func NewRetainListBuilder() *RetainListBuilder {
+ return &RetainListBuilder{
+ proofCodes: make(map[common.Hash][]byte),
+ createdCodes: make(map[common.Hash]struct{}),
+ }
+}
+
+// AddTouch adds a key (in KEY encoding) into the read/change set of account keys
+func (rlb *RetainListBuilder) AddTouch(touch []byte) {
+ rlb.touches = append(rlb.touches, common.CopyBytes(touch))
+}
+
+// AddStorageTouch adds a key (in KEY encoding) into the read/change set of storage keys
+func (rlb *RetainListBuilder) AddStorageTouch(touch []byte) {
+ rlb.storageTouches = append(rlb.storageTouches, common.CopyBytes(touch))
+}
+
+// ExtractTouches returns accumulated read/change sets and clears them for the next block's execution
+func (rlb *RetainListBuilder) ExtractTouches() ([][]byte, [][]byte) {
+ touches := rlb.touches
+ storageTouches := rlb.storageTouches
+ rlb.touches = nil
+ rlb.storageTouches = nil
+ return touches, storageTouches
+}
+
+// extractCodeTouches returns the set of all contract codes that were required during the block's execution
+// but were not created during that same block. It also clears the set for the next block's execution
+func (rlb *RetainListBuilder) extractCodeTouches() map[common.Hash][]byte {
+ proofCodes := rlb.proofCodes
+ rlb.proofCodes = make(map[common.Hash][]byte)
+ rlb.createdCodes = make(map[common.Hash]struct{})
+ return proofCodes
+}
+
+// ReadCode registers that given contract code has been accessed during current block's execution
+func (rlb *RetainListBuilder) ReadCode(codeHash common.Hash, code []byte) {
+ if _, ok := rlb.proofCodes[codeHash]; !ok {
+ rlb.proofCodes[codeHash] = code
+ }
+}
+
+// CreateCode registers that given contract code has been created (deployed) during current block's execution
+func (rlb *RetainListBuilder) CreateCode(codeHash common.Hash) {
+ if _, ok := rlb.proofCodes[codeHash]; !ok {
+ rlb.createdCodes[codeHash] = struct{}{}
+ }
+}
+
+func (rlb *RetainListBuilder) Build(isBinary bool) *RetainList {
+ var rl *RetainList = NewRetainList(0)
+
+ touches, storageTouches := rlb.ExtractTouches()
+ codeTouches := rlb.extractCodeTouches()
+
+ for _, touch := range touches {
+ rl.AddKey(touch)
+ }
+ for _, touch := range storageTouches {
+ rl.AddKey(touch)
+ }
+ for codeHash := range codeTouches {
+ rl.AddCodeTouch(codeHash)
+ }
+
+ return rl
+}
+
+func (rlb *RetainListBuilder) Copy() *RetainListBuilder {
+ rlbCopy := NewRetainListBuilder()
+ for _, touch := range rlb.touches {
+ rlbCopy.AddTouch(touch)
+ }
+ for _, touch := range rlb.storageTouches {
+ rlbCopy.AddStorageTouch(touch)
+ }
+ for codeHash, code := range rlb.proofCodes {
+ rlbCopy.ReadCode(codeHash, code)
+ }
+ for codeHash := range rlb.createdCodes {
+ rlbCopy.CreateCode(codeHash)
+ }
+ return rlbCopy
+}
diff --git a/erigon-lib/trie/retain_list_test.go b/erigon-lib/trie/retain_list_test.go
index 8ea96798208..7b0ffd58b29 100644
--- a/erigon-lib/trie/retain_list_test.go
+++ b/erigon-lib/trie/retain_list_test.go
@@ -39,7 +39,7 @@ func FakePreimage(hash libcommon.Hash) libcommon.Hash {
// manually construct a ProofRetainer based on a set of keys. This is
// especially useful for tests which want to manually manipulate the hash
// databases without worrying about generating and tracking pre-images.
-func NewManualProofRetainer(t *testing.T, acc *accounts.Account, rl *RetainList, keys [][]byte) *ProofRetainer {
+func NewManualProofRetainer(t *testing.T, acc *accounts.Account, rl *RetainList, keys [][]byte) *DefaultProofRetainer {
t.Helper()
var accHexKey []byte
var storageKeys []libcommon.Hash
@@ -60,7 +60,7 @@ func NewManualProofRetainer(t *testing.T, acc *accounts.Account, rl *RetainList,
require.Fail(t, "unexpected key length %d", len(key))
}
}
- return &ProofRetainer{
+ return &DefaultProofRetainer{
rl: rl,
acc: acc,
accHexKey: accHexKey,
diff --git a/erigon-lib/trie/stream.go b/erigon-lib/trie/stream.go
index ce5bd1593ff..1875fa98174 100644
--- a/erigon-lib/trie/stream.go
+++ b/erigon-lib/trie/stream.go
@@ -98,7 +98,7 @@ type StreamIterator interface {
type Iterator struct {
rl *RetainList
hex []byte
- nodeStack []node
+ nodeStack []Node
iStack []int
goDeepStack []bool
lenStack []int
@@ -112,7 +112,7 @@ func NewIterator(t *Trie, rl *RetainList, trace bool) *Iterator {
return &Iterator{
rl: rl,
hex: []byte{},
- nodeStack: []node{t.root},
+ nodeStack: []Node{t.RootNode},
iStack: []int{0},
goDeepStack: []bool{true},
lenStack: []int{0},
@@ -129,7 +129,7 @@ func (it *Iterator) Reset(t *Trie, rl *RetainList, trace bool) {
if len(it.nodeStack) > 0 {
it.nodeStack = it.nodeStack[:0]
}
- it.nodeStack = append(it.nodeStack, t.root)
+ it.nodeStack = append(it.nodeStack, t.RootNode)
if len(it.iStack) > 0 {
it.iStack = it.iStack[:0]
}
@@ -161,13 +161,13 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
switch n := nd.(type) {
case nil:
return NoItem, nil, nil, nil, nil
- case valueNode:
+ case ValueNode:
if it.trace {
fmt.Printf("valueNode %x\n", hex)
}
it.top--
return StorageStreamItem, hex, nil, nil, n
- case *shortNode:
+ case *ShortNode:
if it.trace {
fmt.Printf("shortNode %x\n", hex)
}
@@ -177,20 +177,20 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
}
hex = append(hex, nKey...)
switch v := n.Val.(type) {
- case hashNode:
+ case HashNode:
it.top--
if accounts {
return AHashStreamItem, hex, nil, v.hash, nil
}
return SHashStreamItem, hex, nil, v.hash, nil
- case valueNode:
+ case ValueNode:
it.top--
return StorageStreamItem, hex, nil, nil, v
- case *accountNode:
+ case *AccountNode:
if it.trace {
fmt.Printf("accountNode %x\n", hex)
}
- if v.storage != nil {
+ if v.Storage != nil {
binary.BigEndian.PutUint64(bytes8[:], v.Incarnation)
// Add decompressed incarnation to the hex
for i, b := range bytes8[:] {
@@ -198,7 +198,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
bytes16[i*2+1] = b % 16
}
it.hex = append(hex, bytes16[:]...)
- it.nodeStack[l] = v.storage
+ it.nodeStack[l] = v.Storage
it.iStack[l] = 0
it.goDeepStack[l] = true
it.lenStack[l] = len(it.hex)
@@ -214,7 +214,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
it.goDeepStack[l] = it.rl.Retain(hex)
it.lenStack[l] = len(hex)
it.accountStack[l] = accounts
- case *duoNode:
+ case *DuoNode:
if it.trace {
fmt.Printf("duoNode %x\n", hex)
}
@@ -232,12 +232,12 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
hex = append(hex, i1)
var childGoDeep bool
switch v := n.child1.(type) {
- case hashNode:
+ case HashNode:
if accounts {
return AHashStreamItem, hex, nil, v.hash, nil
}
return SHashStreamItem, hex, nil, v.hash, nil
- case *duoNode:
+ case *DuoNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
if accounts {
@@ -245,7 +245,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
}
return SHashStreamItem, hex, nil, v.reference(), nil
}
- case *fullNode:
+ case *FullNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
if accounts {
@@ -274,13 +274,13 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
hex = append(hex, i2)
var childGoDeep bool
switch v := n.child2.(type) {
- case hashNode:
+ case HashNode:
it.top--
if accounts {
return AHashStreamItem, hex, nil, v.hash, nil
}
return SHashStreamItem, hex, nil, v.hash, nil
- case *duoNode:
+ case *DuoNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
it.top--
@@ -289,7 +289,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
}
return SHashStreamItem, hex, nil, v.reference(), nil
}
- case *fullNode:
+ case *FullNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
it.top--
@@ -306,7 +306,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
it.lenStack[l] = len(hex)
it.accountStack[l] = accounts
}
- case *fullNode:
+ case *FullNode:
if it.trace {
fmt.Printf("fullNode %x\n", hex)
}
@@ -338,12 +338,12 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
hex = append(hex, byte(i1))
var childGoDeep bool
switch v := n.Children[i1].(type) {
- case hashNode:
+ case HashNode:
if accounts {
return AHashStreamItem, hex, nil, v.hash, nil
}
return SHashStreamItem, hex, nil, v.hash, nil
- case *duoNode:
+ case *DuoNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
if accounts {
@@ -351,7 +351,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
}
return SHashStreamItem, hex, nil, v.reference(), nil
}
- case *fullNode:
+ case *FullNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
if accounts {
@@ -380,13 +380,13 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
hex = append(hex, byte(i1))
var childGoDeep bool
switch v := n.Children[i1].(type) {
- case hashNode:
+ case HashNode:
it.top--
if accounts {
return AHashStreamItem, hex, nil, v.hash, nil
}
return SHashStreamItem, hex, nil, v.hash, nil
- case *duoNode:
+ case *DuoNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
it.top--
@@ -395,7 +395,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
}
return SHashStreamItem, hex, nil, v.reference(), nil
}
- case *fullNode:
+ case *FullNode:
childGoDeep = it.rl.Retain(hex)
if !childGoDeep {
it.top--
@@ -412,11 +412,11 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
it.lenStack[l] = len(hex)
it.accountStack[l] = accounts
}
- case *accountNode:
+ case *AccountNode:
if it.trace {
fmt.Printf("accountNode %x\n", hex)
}
- if n.storage != nil {
+ if n.Storage != nil {
binary.BigEndian.PutUint64(bytes8[:], n.Incarnation)
// Add decompressed incarnation to the hex
for i, b := range bytes8[:] {
@@ -424,7 +424,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
bytes16[i*2+1] = b % 16
}
it.hex = append(hex, bytes16[:]...)
- it.nodeStack[l] = n.storage
+ it.nodeStack[l] = n.Storage
it.iStack[l] = 0
it.goDeepStack[l] = true
it.lenStack[l] = len(it.hex)
@@ -433,7 +433,7 @@ func (it *Iterator) Next() (itemType StreamItem, hex1 []byte, aValue *accounts.A
it.top--
}
return AccountStreamItem, hex, &n.Account, nil, nil
- case hashNode:
+ case HashNode:
if it.trace {
fmt.Printf("hashNode %x\n", hex)
}
@@ -772,7 +772,7 @@ func StreamHash(it *StreamMergeIterator, storagePrefixLen int, hb *HashBuilder,
}
if trace {
tt := New(common.Hash{})
- tt.root = hb.root()
+ tt.RootNode = hb.root()
filename := "root.txt"
f, err1 := os.Create(filename)
if err1 == nil {
diff --git a/erigon-lib/trie/structural_test.go b/erigon-lib/trie/structural_test.go
index cda3ecaccb6..f947681a2b7 100644
--- a/erigon-lib/trie/structural_test.go
+++ b/erigon-lib/trie/structural_test.go
@@ -164,7 +164,7 @@ func TestV2Resolution(t *testing.T) {
t.Errorf("Could not execute step of structGen algorithm: %v", err)
}
tr1 := New(common.Hash{})
- tr1.root = hb.root()
+ tr1.RootNode = hb.root()
builtHash := hb.rootHash()
if trieHash != builtHash {
t.Errorf("Expected hash %x, got %x", trieHash, builtHash)
@@ -247,7 +247,7 @@ func TestEmbeddedStorage(t *testing.T) {
builtHash := hb.rootHash()
if trieHash != builtHash {
fmt.Printf("Trie built: %s\n", hb.root().fstring(""))
- fmt.Printf("Trie expected: %s\n", tr.root.fstring(""))
+ fmt.Printf("Trie expected: %s\n", tr.RootNode.fstring(""))
t.Errorf("Expected hash %x, got %x", trieHash, builtHash)
}
fmt.Printf("groups: %d\n", len(groups))
diff --git a/erigon-lib/trie/sub_trie_loader.go b/erigon-lib/trie/sub_trie_loader.go
index 576c345e797..59964e2a205 100644
--- a/erigon-lib/trie/sub_trie_loader.go
+++ b/erigon-lib/trie/sub_trie_loader.go
@@ -28,7 +28,7 @@ var emptyHash [32]byte
// sub-tree root hash would be queried
type SubTries struct {
Hashes []libcommon.Hash // Root hashes of the sub-tries
- roots []node // Sub-tries
+ roots []Node // Sub-tries
}
type LoadFunc func(*SubTrieLoader, *RetainList, [][]byte, []int) (SubTries, error)
diff --git a/erigon-lib/trie/trie.go b/erigon-lib/trie/trie.go
index 5fb5c9e7dd9..abbf1d44b4f 100644
--- a/erigon-lib/trie/trie.go
+++ b/erigon-lib/trie/trie.go
@@ -23,11 +23,13 @@ package trie
import (
"bytes"
"encoding/binary"
+ "errors"
"fmt"
+ "reflect"
libcommon "github.com/erigontech/erigon-lib/common"
- "github.com/erigontech/erigon-lib/crypto"
+ "github.com/erigontech/erigon-lib/crypto"
"github.com/erigontech/erigon-lib/types/accounts"
)
@@ -48,10 +50,11 @@ var (
// Deprecated
// use package turbo/trie
type Trie struct {
- root node
+ RootNode Node
valueNodesRLPEncoded bool
newHasherFunc func() *hasher
+ strictHash bool // if true, the trie will panic on a hash access
}
// New creates a trie with an existing root node from db.
@@ -67,11 +70,211 @@ func New(root libcommon.Hash) *Trie {
newHasherFunc: func() *hasher { return newHasher( /*valueNodesRlpEncoded = */ false) },
}
if (root != libcommon.Hash{}) && root != EmptyRoot {
- trie.root = hashNode{hash: root[:]}
+ trie.RootNode = &HashNode{hash: root[:]}
+ }
+ return trie
+}
+
+func NewInMemoryTrie(root Node) *Trie {
+ trie := &Trie{
+ newHasherFunc: func() *hasher { return newHasher( /*valueNodesRlpEncoded = */ false) },
+ RootNode: root,
+ }
+ return trie
+}
+
+func NewInMemoryTrieRLPEncoded(root Node) *Trie {
+ trie := &Trie{
+ newHasherFunc: func() *hasher { return newHasher( /*valueNodesRlpEncoded = */ true) },
+ RootNode: root,
+ valueNodesRLPEncoded: true,
}
return trie
}
+// this will merge node2 into node1, returns a boolean mergeNecessary, if it was necessary to replace a child.
+// If not, then the two full nodes are the same so no replacement was necessary
+// This function also performs certain sanity checks which can result in an error if they fail
+func merge2FullNodes(node1, node2 *FullNode) (bool, error) {
+ furtherMergingNeeded := false
+ for i := 0; i < len(node1.Children); i++ {
+ // either both children are hashnodes, or only one of them is, or none of them is.
+ // if both of the two children (of trie1 and trie2) at a certain index are not hashnodes
+ // they must be the same type (e.g. both a FullNode, or both a ShortNode, or both nil) . If this is true for all children then no merge takes place at this level.
+ child1 := node1.Children[i]
+ child2 := node2.Children[i]
+ if hashNode1, ok1 := child1.(*HashNode); ok1 { // child1 is a hashnode
+ if hashNode2, ok2 := child2.(*HashNode); ok2 { //child2 is a hashnode
+ // both are hashnodes
+ if !bytes.Equal(hashNode1.hash, hashNode2.hash) { // sanity check
+ return false, fmt.Errorf("children hashnodes have different hashes: hash1(%x)!=hash2(%x)", hashNode1.hash, hashNode2.hash)
+ }
+ } else if child2 == nil {
+ return false, fmt.Errorf("child of tr2 should not be nil, because child of tr1 is a hashnode")
+ } else { // child2 is not a hashnode, in this case replace the hashnode in tree 1 by child2 which has the expanded node type
+ node1.Children[i] = child2
+ }
+ } else if child1 == nil {
+ if child2 != nil {
+ // sanity check
+ return false, fmt.Errorf("child of first node is nil , but corresponding child of second node is non-nil")
+ }
+ } else { // child1 is not nil and not a hashnode
+ if _, ok2 := child2.(*HashNode); !ok2 { // if child2 is not hashnode, now they are expected to have the same type , if child2 is a hashnode then no changes are necessary to node1
+ if reflect.TypeOf(child1) != reflect.TypeOf(child2) { // sanity check
+ return false, fmt.Errorf("children have different types: %T != %T", child1, child2)
+ } else { // further merging will be needed at the next level
+ furtherMergingNeeded = true
+ }
+ }
+ }
+ }
+ return furtherMergingNeeded, nil
+}
+
+func merge2ShortNodes(node1, node2 *ShortNode) (bool, error) {
+ furtherMergingNeeded := false
+ if !bytes.Equal(node1.Key, node2.Key) { // sanity check
+ return false, fmt.Errorf("mismatch in the short node keys node1.Key(%x)!=node2.Key(%x)", node1.Key, node2.Key)
+ }
+ if hashNode1, ok1 := node1.Val.(*HashNode); ok1 { // node1.Val is a HashNode
+ if hashNode2, ok2 := node2.Val.(*HashNode); ok2 { // node2.Val is a HashNode
+ // both are hashnodes
+ if !bytes.Equal(hashNode1.hash, hashNode2.hash) { // sanity check
+ return false, fmt.Errorf("hashnodes have different hashes: hash1(%x) != hash2(%x)", hashNode1.hash, hashNode2.hash)
+ }
+ } else if node2.Val == nil {
+ return false, fmt.Errorf("node2.Val should not be nil, because node1.Val is a hashnode")
+ } else { // in this case node2.Val is not a HashNode, while node1.Val is a hash node, so replace node1.Val by node2.Val, and the merging is complete
+ node1.Val = node2.Val
+ }
+ } else { // node1.Val is not a hashnode
+ // if node2.Val is not a hashnode, node2.Val is expected to have the same type as node1.Val, otherwise if it is a hashnode no action is necessary (just ignore the hashnode)
+ if _, ok2 := node2.Val.(*HashNode); !ok2 {
+ if reflect.TypeOf(node1.Val) != reflect.TypeOf(node2.Val) { // sanity check
+ return false, fmt.Errorf("node1.Val and node2.Val have different types: %T != %T ", node1.Val, node2.Val)
+ } else {
+ furtherMergingNeeded = true
+ }
+ }
+ }
+ return furtherMergingNeeded, nil
+}
+
+func merge2AccountNodes(node1, node2 *AccountNode) (furtherMergingNeeded bool) {
+ storage1 := node1.Storage
+ storage2 := node2.Storage
+ if storage1 == nil || storage2 == nil { // in this case do nothing, we can use the storage tree of node 1
+ return false
+ }
+ _, isHashNode1 := storage1.(*HashNode) // check if storage1 is a hashnode
+ _, isHashNode2 := storage2.(*HashNode) // check if storage2 is a hashnode
+ if isHashNode1 && !isHashNode2 { // node2 has the expanded storage trie, so use that instead of the hashnode
+ node1.Storage = storage2
+ return false
+ }
+
+ if !isHashNode1 && !isHashNode2 { // the 2 storage tries need to be merged
+ return true
+ }
+ return false
+}
+
+func merge2Tries(tr1 *Trie, tr2 *Trie) (*Trie, error) {
+ // starting from the roots merge each level
+ rootNode1 := tr1.RootNode
+ rootNode2 := tr2.RootNode
+ mergeComplete := false
+
+ for !mergeComplete {
+ switch node1 := (rootNode1).(type) {
+ case nil:
+ // sanity checks might be good later on
+ return nil, nil
+ case *ShortNode:
+ node2, ok := rootNode2.(*ShortNode)
+ if !ok {
+ return nil, fmt.Errorf("expected *trie.ShortNode in trie 2, but got %T", rootNode2)
+ }
+ furtherMergingNeeded, err := merge2ShortNodes(node1, node2)
+ if err != nil {
+ return nil, err
+ }
+ if furtherMergingNeeded {
+ rootNode1 = node1.Val
+ rootNode2 = node2.Val
+ } else {
+ mergeComplete = true
+ }
+ case *FullNode:
+ node2, ok := rootNode2.(*FullNode)
+ if !ok {
+ return nil, fmt.Errorf("expected *trie.FullNode in trie 2, but got %T", rootNode2)
+ }
+ furthedMergingNeeded, err := merge2FullNodes(node1, node2)
+ if err != nil {
+ return nil, err
+ }
+ if furthedMergingNeeded { // find the next nodes to merge
+ nextRootsFound := false
+ for i := 0; i < len(node1.Children); i++ { // it is guaranteed that we will find a non-nil, non-hashnode
+ childNode1 := node1.Children[i]
+ childNode2 := node2.Children[i]
+ if _, isHashNode := childNode2.(*HashNode); childNode2 != nil && !isHashNode {
+ // update rootNode1, and rootNode2 to merge at the next level at the next iteration
+ rootNode1 = childNode1
+ rootNode2 = childNode2
+ nextRootsFound = true
+ break
+ }
+ }
+ if !nextRootsFound {
+ return nil, errors.New("could not find next node pair to merge")
+ }
+ } else {
+ mergeComplete = true
+ }
+ case *HashNode:
+ return tr2, nil
+ case ValueNode:
+ return tr1, nil
+ case *AccountNode:
+ node2, ok := rootNode2.(*AccountNode)
+ if !ok {
+ return nil, fmt.Errorf("expected *trie.AccountNode in trie 2, but got %T", rootNode2)
+ }
+ furthedMergingNeeded := merge2AccountNodes(node1, node2)
+ if !furthedMergingNeeded {
+ return tr1, nil
+ } else {
+ // need to merge storage trees
+ rootNode1 = node1.Storage
+ rootNode2 = node2.Storage
+ }
+
+ }
+ }
+ return tr1, nil
+}
+func MergeTries(tries []*Trie) (*Trie, error) {
+ if len(tries) == 0 {
+ return nil, nil
+ }
+
+ if len(tries) == 1 {
+ return tries[0], nil
+ }
+
+ resultingTrie := tries[0]
+ for i := 1; i < len(tries); i++ {
+ resultingTrie, err := merge2Tries(resultingTrie, tries[i])
+ if err != nil {
+ return resultingTrie, err
+ }
+ }
+ return resultingTrie, nil
+}
+
// NewTestRLPTrie treats all the data provided to `Update` function as rlp-encoded.
// it is usually used for testing purposes.
func NewTestRLPTrie(root libcommon.Hash) *Trie {
@@ -80,38 +283,42 @@ func NewTestRLPTrie(root libcommon.Hash) *Trie {
newHasherFunc: func() *hasher { return newHasher( /*valueNodesRlpEncoded = */ true) },
}
if (root != libcommon.Hash{}) && root != EmptyRoot {
- trie.root = hashNode{hash: root[:]}
+ trie.RootNode = &HashNode{hash: root[:]}
}
return trie
}
+func (t *Trie) SetStrictHash(strict bool) {
+ t.strictHash = strict
+}
+
// Get returns the value for key stored in the trie.
func (t *Trie) Get(key []byte) (value []byte, gotValue bool) {
- if t.root == nil {
+ if t.RootNode == nil {
return nil, true
}
hex := keybytesToHex(key)
- return t.get(t.root, hex, 0)
+ return t.get(t.RootNode, hex, 0)
}
func (t *Trie) FindPath(key []byte) (value []byte, parents [][]byte, gotValue bool) {
- if t.root == nil {
+ if t.RootNode == nil {
return nil, nil, true
}
hex := keybytesToHex(key)
- return t.getPath(t.root, nil, hex, 0)
+ return t.getPath(t.RootNode, nil, hex, 0)
}
func (t *Trie) GetAccount(key []byte) (value *accounts.Account, gotValue bool) {
- if t.root == nil {
+ if t.RootNode == nil {
return nil, true
}
hex := keybytesToHex(key)
- accNode, gotValue := t.getAccount(t.root, hex, 0)
+ accNode, gotValue := t.getAccount(t.RootNode, hex, 0)
if accNode != nil {
var value accounts.Account
value.Copy(&accNode.Account)
@@ -121,57 +328,57 @@ func (t *Trie) GetAccount(key []byte) (value *accounts.Account, gotValue bool) {
}
func (t *Trie) GetAccountCode(key []byte) (value []byte, gotValue bool) {
- if t.root == nil {
+ if t.RootNode == nil {
return nil, false
}
hex := keybytesToHex(key)
- accNode, gotValue := t.getAccount(t.root, hex, 0)
+ accNode, gotValue := t.getAccount(t.RootNode, hex, 0)
if accNode != nil {
if bytes.Equal(accNode.Account.CodeHash[:], EmptyCodeHash[:]) {
return nil, gotValue
}
- if accNode.code == nil {
+ if accNode.Code == nil {
return nil, false
}
- return accNode.code, gotValue
+ return accNode.Code, gotValue
}
return nil, gotValue
}
func (t *Trie) GetAccountCodeSize(key []byte) (value int, gotValue bool) {
- if t.root == nil {
+ if t.RootNode == nil {
return 0, false
}
hex := keybytesToHex(key)
- accNode, gotValue := t.getAccount(t.root, hex, 0)
+ accNode, gotValue := t.getAccount(t.RootNode, hex, 0)
if accNode != nil {
if bytes.Equal(accNode.Account.CodeHash[:], EmptyCodeHash[:]) {
return 0, gotValue
}
- if accNode.codeSize == codeSizeUncached {
+ if accNode.CodeSize == codeSizeUncached {
return 0, false
}
- return accNode.codeSize, gotValue
+ return accNode.CodeSize, gotValue
}
return 0, gotValue
}
-func (t *Trie) getAccount(origNode node, key []byte, pos int) (value *accountNode, gotValue bool) {
+func (t *Trie) getAccount(origNode Node, key []byte, pos int) (value *AccountNode, gotValue bool) {
switch n := (origNode).(type) {
case nil:
return nil, true
- case *shortNode:
+ case *ShortNode:
matchlen := prefixLen(key[pos:], n.Key)
if matchlen == len(n.Key) {
- if v, ok := n.Val.(*accountNode); ok {
+ if v, ok := n.Val.(*AccountNode); ok {
return v, true
} else {
return t.getAccount(n.Val, key, pos+matchlen)
@@ -179,7 +386,7 @@ func (t *Trie) getAccount(origNode node, key []byte, pos int) (value *accountNod
} else {
return nil, true
}
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
switch key[pos] {
case i1:
@@ -189,28 +396,28 @@ func (t *Trie) getAccount(origNode node, key []byte, pos int) (value *accountNod
default:
return nil, true
}
- case *fullNode:
+ case *FullNode:
child := n.Children[key[pos]]
return t.getAccount(child, key, pos+1)
- case hashNode:
+ case *HashNode:
return nil, false
- case *accountNode:
+ case *AccountNode:
return n, true
default:
panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode))
}
}
-func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, gotValue bool) {
+func (t *Trie) get(origNode Node, key []byte, pos int) (value []byte, gotValue bool) {
switch n := (origNode).(type) {
case nil:
return nil, true
- case valueNode:
+ case ValueNode:
return n, true
- case *accountNode:
- return t.get(n.storage, key, pos)
- case *shortNode:
+ case *AccountNode:
+ return t.get(n.Storage, key, pos)
+ case *ShortNode:
matchlen := prefixLen(key[pos:], n.Key)
if matchlen == len(n.Key) || n.Key[matchlen] == 16 {
value, gotValue = t.get(n.Val, key, pos+matchlen)
@@ -218,7 +425,7 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, gotValue b
value, gotValue = nil, true
}
return
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
switch key[pos] {
case i1:
@@ -229,13 +436,13 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, gotValue b
value, gotValue = nil, true
}
return
- case *fullNode:
+ case *FullNode:
child := n.Children[key[pos]]
if child == nil {
return nil, true
}
return t.get(child, key, pos+1)
- case hashNode:
+ case *HashNode:
return n.hash, false
default:
@@ -243,15 +450,15 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, gotValue b
}
}
-func (t *Trie) getPath(origNode node, parents [][]byte, key []byte, pos int) ([]byte, [][]byte, bool) {
+func (t *Trie) getPath(origNode Node, parents [][]byte, key []byte, pos int) ([]byte, [][]byte, bool) {
switch n := (origNode).(type) {
case nil:
return nil, parents, true
- case valueNode:
+ case ValueNode:
return n, parents, true
- case *accountNode:
- return t.getPath(n.storage, append(parents, n.reference()), key, pos)
- case *shortNode:
+ case *AccountNode:
+ return t.getPath(n.Storage, append(parents, n.reference()), key, pos)
+ case *ShortNode:
matchlen := prefixLen(key[pos:], n.Key)
if matchlen == len(n.Key) || n.Key[matchlen] == 16 {
return t.getPath(n.Val, append(parents, n.reference()), key, pos+matchlen)
@@ -259,7 +466,7 @@ func (t *Trie) getPath(origNode node, parents [][]byte, key []byte, pos int) ([]
return nil, parents, true
}
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
switch key[pos] {
case i1:
@@ -269,13 +476,13 @@ func (t *Trie) getPath(origNode node, parents [][]byte, key []byte, pos int) ([]
default:
return nil, parents, true
}
- case *fullNode:
+ case *FullNode:
child := n.Children[key[pos]]
if child == nil {
return nil, parents, true
}
return t.getPath(child, append(parents, n.reference()), key, pos+1)
- case hashNode:
+ case *HashNode:
return n.hash, parents, false
default:
@@ -293,12 +500,12 @@ func (t *Trie) getPath(origNode node, parents [][]byte, key []byte, pos int) ([]
func (t *Trie) Update(key, value []byte) {
hex := keybytesToHex(key)
- newnode := valueNode(value)
+ newnode := ValueNode(value)
- if t.root == nil {
- t.root = NewShortNode(hex, newnode)
+ if t.RootNode == nil {
+ t.RootNode = NewShortNode(hex, newnode)
} else {
- _, t.root = t.insert(t.root, hex, valueNode(value))
+ _, t.RootNode = t.insert(t.RootNode, hex, ValueNode(value))
}
}
@@ -309,29 +516,29 @@ func (t *Trie) UpdateAccount(key []byte, acc *accounts.Account) {
hex := keybytesToHex(key)
- var newnode *accountNode
+ var newnode *AccountNode
if value.Root == EmptyRoot || value.Root == (libcommon.Hash{}) {
- newnode = &accountNode{*value, nil, true, nil, codeSizeUncached}
+ newnode = &AccountNode{*value, nil, true, nil, codeSizeUncached}
} else {
- newnode = &accountNode{*value, hashNode{hash: value.Root[:]}, true, nil, codeSizeUncached}
+ newnode = &AccountNode{*value, HashNode{hash: value.Root[:]}, true, nil, codeSizeUncached}
}
- if t.root == nil {
- t.root = NewShortNode(hex, newnode)
+ if t.RootNode == nil {
+ t.RootNode = NewShortNode(hex, newnode)
} else {
- _, t.root = t.insert(t.root, hex, newnode)
+ _, t.RootNode = t.insert(t.RootNode, hex, newnode)
}
}
// UpdateAccountCode attaches the code node to an account at specified key
-func (t *Trie) UpdateAccountCode(key []byte, code codeNode) error {
- if t.root == nil {
+func (t *Trie) UpdateAccountCode(key []byte, code CodeNode) error {
+ if t.RootNode == nil {
return nil
}
hex := keybytesToHex(key)
- accNode, gotValue := t.getAccount(t.root, hex, 0)
+ accNode, gotValue := t.getAccount(t.RootNode, hex, 0)
if accNode == nil || !gotValue {
return fmt.Errorf("account not found with key: %x", key)
}
@@ -341,31 +548,31 @@ func (t *Trie) UpdateAccountCode(key []byte, code codeNode) error {
return fmt.Errorf("inserted code mismatch account hash (acc.CodeHash=%x codeHash=%x)", accNode.CodeHash[:], actualCodeHash)
}
- accNode.code = code
- accNode.codeSize = len(code)
+ accNode.Code = code
+ accNode.CodeSize = len(code)
// t.insert will call the observer methods itself
- _, t.root = t.insert(t.root, hex, accNode)
+ _, t.RootNode = t.insert(t.RootNode, hex, accNode)
return nil
}
// UpdateAccountCodeSize attaches the code size to the account
func (t *Trie) UpdateAccountCodeSize(key []byte, codeSize int) error {
- if t.root == nil {
+ if t.RootNode == nil {
return nil
}
hex := keybytesToHex(key)
- accNode, gotValue := t.getAccount(t.root, hex, 0)
+ accNode, gotValue := t.getAccount(t.RootNode, hex, 0)
if accNode == nil || !gotValue {
return fmt.Errorf("account not found with key: %x", key)
}
- accNode.codeSize = codeSize
+ accNode.CodeSize = codeSize
// t.insert will call the observer methods itself
- _, t.root = t.insert(t.root, hex, accNode)
+ _, t.RootNode = t.insert(t.RootNode, hex, accNode)
return nil
}
@@ -410,15 +617,15 @@ func (t *Trie) NeedLoadCode(addrHash libcommon.Hash, codeHash libcommon.Hash, by
// It also create list of `hooks`, the paths in the trie (in nibbles) where the loaded
// sub-tries need to be inserted.
func (t *Trie) FindSubTriesToLoad(rl RetainDecider) (prefixes [][]byte, fixedbits []int, hooks [][]byte) {
- return findSubTriesToLoad(t.root, nil, nil, rl, nil, 0, nil, nil, nil)
+ return findSubTriesToLoad(t.RootNode, nil, nil, rl, nil, 0, nil, nil, nil)
}
var bytes8 [8]byte
var bytes16 [16]byte
-func findSubTriesToLoad(nd node, nibblePath []byte, hook []byte, rl RetainDecider, dbPrefix []byte, bits int, prefixes [][]byte, fixedbits []int, hooks [][]byte) (newPrefixes [][]byte, newFixedBits []int, newHooks [][]byte) {
+func findSubTriesToLoad(nd Node, nibblePath []byte, hook []byte, rl RetainDecider, dbPrefix []byte, bits int, prefixes [][]byte, fixedbits []int, hooks [][]byte) (newPrefixes [][]byte, newFixedBits []int, newHooks [][]byte) {
switch n := nd.(type) {
- case *shortNode:
+ case *ShortNode:
nKey := n.Key
if nKey[len(nKey)-1] == 16 {
nKey = nKey[:len(nKey)-1]
@@ -438,7 +645,7 @@ func findSubTriesToLoad(nd node, nibblePath []byte, hook []byte, rl RetainDecide
bits += 4
}
return findSubTriesToLoad(n.Val, nibblePath, hook, rl, dbPrefix, bits, prefixes, fixedbits, hooks)
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
newPrefixes = prefixes
newFixedBits = fixedbits
@@ -470,7 +677,7 @@ func findSubTriesToLoad(nd node, nibblePath []byte, hook []byte, rl RetainDecide
newPrefixes, newFixedBits, newHooks = findSubTriesToLoad(n.child2, newNibblePath, newHook, rl, newDbPrefix, bits+4, newPrefixes, newFixedBits, newHooks)
}
return newPrefixes, newFixedBits, newHooks
- case *fullNode:
+ case *FullNode:
newPrefixes = prefixes
newFixedBits = fixedbits
newHooks = hooks
@@ -494,8 +701,8 @@ func findSubTriesToLoad(nd node, nibblePath []byte, hook []byte, rl RetainDecide
}
}
return newPrefixes, newFixedBits, newHooks
- case *accountNode:
- if n.storage == nil {
+ case *AccountNode:
+ if n.Storage == nil {
return prefixes, fixedbits, hooks
}
binary.BigEndian.PutUint64(bytes8[:], n.Incarnation)
@@ -510,10 +717,10 @@ func findSubTriesToLoad(nd node, nibblePath []byte, hook []byte, rl RetainDecide
newFixedBits = fixedbits
newHooks = hooks
if rl.Retain(nibblePath) {
- newPrefixes, newFixedBits, newHooks = findSubTriesToLoad(n.storage, nibblePath, hook, rl, dbPrefix, bits+64, prefixes, fixedbits, hooks)
+ newPrefixes, newFixedBits, newHooks = findSubTriesToLoad(n.Storage, nibblePath, hook, rl, dbPrefix, bits+64, prefixes, fixedbits, hooks)
}
return newPrefixes, newFixedBits, newHooks
- case hashNode:
+ case *HashNode:
newPrefixes = append(prefixes, libcommon.Copy(dbPrefix))
newFixedBits = append(fixedbits, bits)
newHooks = append(hooks, libcommon.Copy(hook))
@@ -524,14 +731,14 @@ func findSubTriesToLoad(nd node, nibblePath []byte, hook []byte, rl RetainDecide
// can pass incarnation=0 if start from root, method internally will
// put incarnation from accountNode when pass it by traverse
-func (t *Trie) insert(origNode node, key []byte, value node) (updated bool, newNode node) {
+func (t *Trie) insert(origNode Node, key []byte, value Node) (updated bool, newNode Node) {
return t.insertRecursive(origNode, key, 0, value)
}
-func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (updated bool, newNode node) {
+func (t *Trie) insertRecursive(origNode Node, key []byte, pos int, value Node) (updated bool, newNode Node) {
if len(key) == pos {
- origN, origNok := origNode.(valueNode)
- vn, vnok := value.(valueNode)
+ origN, origNok := origNode.(ValueNode)
+ vn, vnok := value.(ValueNode)
if origNok && vnok {
updated = !bytes.Equal(origN, vn)
if updated {
@@ -541,19 +748,19 @@ func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (
}
return
}
- origAccN, origNok := origNode.(*accountNode)
- vAccN, vnok := value.(*accountNode)
+ origAccN, origNok := origNode.(*AccountNode)
+ vAccN, vnok := value.(*AccountNode)
if origNok && vnok {
updated = !origAccN.Equals(&vAccN.Account)
if updated {
if !bytes.Equal(origAccN.CodeHash[:], vAccN.CodeHash[:]) {
- origAccN.code = nil
- } else if vAccN.code != nil {
- origAccN.code = vAccN.code
+ origAccN.Code = nil
+ } else if vAccN.Code != nil {
+ origAccN.Code = vAccN.Code
}
origAccN.Account.Copy(&vAccN.Account)
- origAccN.codeSize = vAccN.codeSize
- origAccN.rootCorrect = false
+ origAccN.CodeSize = vAccN.CodeSize
+ origAccN.RootCorrect = false
}
newNode = origAccN
return
@@ -565,18 +772,18 @@ func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (
}
}
- var nn node
+ var nn Node
switch n := origNode.(type) {
case nil:
return true, NewShortNode(libcommon.Copy(key[pos:]), value)
- case *accountNode:
- updated, nn = t.insertRecursive(n.storage, key, pos, value)
+ case *AccountNode:
+ updated, nn = t.insertRecursive(n.Storage, key, pos, value)
if updated {
- n.storage = nn
- n.rootCorrect = false
+ n.Storage = nn
+ n.RootCorrect = false
}
return updated, n
- case *shortNode:
+ case *ShortNode:
matchlen := prefixLen(key[pos:], n.Key)
// If the whole key matches, keep this short node as is
// and only update the value.
@@ -589,19 +796,19 @@ func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (
newNode = n
} else {
// Otherwise branch out at the index where they differ.
- var c1 node
+ var c1 Node
if len(n.Key) == matchlen+1 {
c1 = n.Val
} else {
c1 = NewShortNode(libcommon.Copy(n.Key[matchlen+1:]), n.Val)
}
- var c2 node
+ var c2 Node
if len(key) == pos+matchlen+1 {
c2 = value
} else {
c2 = NewShortNode(libcommon.Copy(key[pos+matchlen+1:]), value)
}
- branch := &duoNode{}
+ branch := &DuoNode{}
if n.Key[matchlen] < key[pos+matchlen] {
branch.child1 = c1
branch.child2 = c2
@@ -625,7 +832,7 @@ func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (
}
return
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
switch key[pos] {
case i1:
@@ -643,13 +850,13 @@ func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (
}
newNode = n
default:
- var child node
+ var child Node
if len(key) == pos+1 {
child = value
} else {
child = NewShortNode(libcommon.Copy(key[pos+1:]), value)
}
- newnode := &fullNode{}
+ newnode := &FullNode{}
newnode.Children[i1] = n.child1
newnode.Children[i2] = n.child2
newnode.Children[key[pos]] = child
@@ -659,7 +866,7 @@ func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (
}
return
- case *fullNode:
+ case *FullNode:
child := n.Children[key[pos]]
if child == nil {
if len(key) == pos+1 {
@@ -684,9 +891,9 @@ func (t *Trie) insertRecursive(origNode node, key []byte, pos int, value node) (
}
// non-recursive version of get and returns: node and parent node
-func (t *Trie) getNode(hex []byte, doTouch bool) (node, node, bool, uint64) {
- var nd = t.root
- var parent node
+func (t *Trie) getNode(hex []byte, doTouch bool) (Node, Node, bool, uint64) {
+ var nd = t.RootNode
+ var parent Node
pos := 0
var account bool
var incarnation uint64
@@ -694,19 +901,19 @@ func (t *Trie) getNode(hex []byte, doTouch bool) (node, node, bool, uint64) {
switch n := nd.(type) {
case nil:
return nil, nil, false, incarnation
- case *shortNode:
+ case *ShortNode:
matchlen := prefixLen(hex[pos:], n.Key)
if matchlen == len(n.Key) || n.Key[matchlen] == 16 {
parent = n
nd = n.Val
pos += matchlen
- if _, ok := nd.(*accountNode); ok {
+ if _, ok := nd.(*AccountNode); ok {
account = true
}
} else {
return nil, nil, false, incarnation
}
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
switch hex[pos] {
case i1:
@@ -720,7 +927,7 @@ func (t *Trie) getNode(hex []byte, doTouch bool) (node, node, bool, uint64) {
default:
return nil, nil, false, incarnation
}
- case *fullNode:
+ case *FullNode:
child := n.Children[hex[pos]]
if child == nil {
return nil, nil, false, incarnation
@@ -728,14 +935,14 @@ func (t *Trie) getNode(hex []byte, doTouch bool) (node, node, bool, uint64) {
parent = n
nd = child
pos++
- case *accountNode:
+ case *AccountNode:
parent = n
- nd = n.storage
+ nd = n.Storage
incarnation = n.Incarnation
account = false
- case valueNode:
+ case ValueNode:
return nd, parent, true, incarnation
- case hashNode:
+ case HashNode:
return nd, parent, true, incarnation
default:
panic(fmt.Sprintf("Unknown node: %T", n))
@@ -758,15 +965,15 @@ func (t *Trie) HookSubTries(subTries SubTries, hooks [][]byte) error {
return nil
}
-func (t *Trie) hook(hex []byte, n node, hash []byte) error {
+func (t *Trie) hook(hex []byte, n Node, hash []byte) error {
nd, parent, ok, incarnation := t.getNode(hex, true)
if !ok {
return nil
}
- if _, ok := nd.(valueNode); ok {
+ if _, ok := nd.(ValueNode); ok {
return nil
}
- if hn, ok := nd.(hashNode); ok {
+ if hn, ok := nd.(HashNode); ok {
if !bytes.Equal(hn.hash, hash) {
return fmt.Errorf("wrong hash when hooking, expected %s, sub-tree hash %x", hn, hash)
}
@@ -777,10 +984,10 @@ func (t *Trie) hook(hex []byte, n node, hash []byte) error {
t.touchAll(n, hex, false, incarnation)
switch p := parent.(type) {
case nil:
- t.root = n
- case *shortNode:
+ t.RootNode = n
+ case *ShortNode:
p.Val = n
- case *duoNode:
+ case *DuoNode:
i1, i2 := p.childrenIdx()
switch hex[len(hex)-1] {
case i1:
@@ -788,19 +995,19 @@ func (t *Trie) hook(hex []byte, n node, hash []byte) error {
case i2:
p.child2 = n
}
- case *fullNode:
+ case *FullNode:
idx := hex[len(hex)-1]
p.Children[idx] = n
- case *accountNode:
- p.storage = n
+ case *AccountNode:
+ p.Storage = n
}
return nil
}
-func (t *Trie) touchAll(n node, hex []byte, del bool, incarnation uint64) {
+func (t *Trie) touchAll(n Node, hex []byte, del bool, incarnation uint64) {
switch n := n.(type) {
- case *shortNode:
- if _, ok := n.Val.(valueNode); !ok {
+ case *ShortNode:
+ if _, ok := n.Val.(ValueNode); !ok {
// Don't need to compute prefix for a leaf
h := n.Key
// Remove terminator
@@ -810,7 +1017,7 @@ func (t *Trie) touchAll(n node, hex []byte, del bool, incarnation uint64) {
hexVal := concat(hex, h...)
t.touchAll(n.Val, hexVal, del, incarnation)
}
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
hex1 := make([]byte, len(hex)+1)
copy(hex1, hex)
@@ -820,15 +1027,15 @@ func (t *Trie) touchAll(n node, hex []byte, del bool, incarnation uint64) {
hex2[len(hex)] = i2
t.touchAll(n.child1, hex1, del, incarnation)
t.touchAll(n.child2, hex2, del, incarnation)
- case *fullNode:
+ case *FullNode:
for i, child := range n.Children {
if child != nil {
t.touchAll(child, concat(hex, byte(i)), del, incarnation)
}
}
- case *accountNode:
- if n.storage != nil {
- t.touchAll(n.storage, hex, del, n.Incarnation)
+ case *AccountNode:
+ if n.Storage != nil {
+ t.touchAll(n.Storage, hex, del, n.Incarnation)
}
}
}
@@ -837,10 +1044,10 @@ func (t *Trie) touchAll(n node, hex []byte, del bool, incarnation uint64) {
// DESCRIBED: docs/programmers_guide/guide.md#root
func (t *Trie) Delete(key []byte) {
hex := keybytesToHex(key)
- _, t.root = t.delete(t.root, hex, false)
+ _, t.RootNode = t.delete(t.RootNode, hex, false)
}
-func (t *Trie) convertToShortNode(child node, pos uint) node {
+func (t *Trie) convertToShortNode(child Node, pos uint) Node {
if pos != 16 {
// If the remaining entry is a short node, it replaces
// n and its key gets the missing nibble tacked to the
@@ -848,7 +1055,7 @@ func (t *Trie) convertToShortNode(child node, pos uint) node {
// shortNode{..., shortNode{...}}. Since the entry
// might not be loaded yet, resolve it just for this
// check.
- if short, ok := child.(*shortNode); ok {
+ if short, ok := child.(*ShortNode); ok {
k := make([]byte, len(short.Key)+1)
k[0] = byte(pos)
copy(k[1:], short.Key)
@@ -860,7 +1067,7 @@ func (t *Trie) convertToShortNode(child node, pos uint) node {
return NewShortNode([]byte{byte(pos)}, child)
}
-func (t *Trie) delete(origNode node, key []byte, preserveAccountNode bool) (updated bool, newNode node) {
+func (t *Trie) delete(origNode Node, key []byte, preserveAccountNode bool) (updated bool, newNode Node) {
return t.deleteRecursive(origNode, key, 0, preserveAccountNode, 0)
}
@@ -870,10 +1077,10 @@ func (t *Trie) delete(origNode node, key []byte, preserveAccountNode bool) (upda
//
// can pass incarnation=0 if start from root, method internally will
// put incarnation from accountNode when pass it by traverse
-func (t *Trie) deleteRecursive(origNode node, key []byte, keyStart int, preserveAccountNode bool, incarnation uint64) (updated bool, newNode node) {
- var nn node
+func (t *Trie) deleteRecursive(origNode Node, key []byte, keyStart int, preserveAccountNode bool, incarnation uint64) (updated bool, newNode Node) {
+ var nn Node
switch n := origNode.(type) {
- case *shortNode:
+ case *ShortNode:
matchlen := prefixLen(key[keyStart:], n.Key)
if matchlen == min(len(n.Key), len(key[keyStart:])) || n.Key[matchlen] == 16 || key[keyStart+matchlen] == 16 {
fullMatch := matchlen == len(key)-keyStart
@@ -902,7 +1109,7 @@ func (t *Trie) deleteRecursive(origNode node, key []byte, keyStart int, preserve
if nn == nil {
newNode = nil
} else {
- if shortChild, ok := nn.(*shortNode); ok {
+ if shortChild, ok := nn.(*ShortNode); ok {
// Deleting from the subtrie reduced it to another
// short node. Merge the nodes to avoid creating a
// shortNode{..., shortNode{...}}. Use concat (which
@@ -924,7 +1131,7 @@ func (t *Trie) deleteRecursive(origNode node, key []byte, keyStart int, preserve
}
return
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
switch key[keyStart] {
case i1:
@@ -959,7 +1166,7 @@ func (t *Trie) deleteRecursive(origNode node, key []byte, keyStart int, preserve
}
return
- case *fullNode:
+ case *FullNode:
child := n.Children[key[keyStart]]
updated, nn = t.deleteRecursive(child, key, keyStart+1, preserveAccountNode, incarnation)
if !updated {
@@ -994,7 +1201,7 @@ func (t *Trie) deleteRecursive(origNode node, key []byte, keyStart int, preserve
if count == 1 {
newNode = t.convertToShortNode(n.Children[pos1], uint(pos1))
} else if count == 2 {
- duo := &duoNode{}
+ duo := &DuoNode{}
if pos1 == int(key[keyStart]) {
duo.child1 = nn
} else {
@@ -1015,36 +1222,36 @@ func (t *Trie) deleteRecursive(origNode node, key []byte, keyStart int, preserve
}
return
- case valueNode:
+ case ValueNode:
updated = true
newNode = nil
return
- case *accountNode:
+ case *AccountNode:
if keyStart >= len(key) || key[keyStart] == 16 {
// Key terminates here
h := key[:keyStart]
if h[len(h)-1] == 16 {
h = h[:len(h)-1]
}
- if n.storage != nil {
+ if n.Storage != nil {
// Mark all the storage nodes as deleted
- t.touchAll(n.storage, h, true, n.Incarnation)
+ t.touchAll(n.Storage, h, true, n.Incarnation)
}
if preserveAccountNode {
- n.storage = nil
- n.code = nil
+ n.Storage = nil
+ n.Code = nil
n.Root = EmptyRoot
- n.rootCorrect = true
+ n.RootCorrect = true
return true, n
}
return true, nil
}
- updated, nn = t.deleteRecursive(n.storage, key, keyStart, preserveAccountNode, n.Incarnation)
+ updated, nn = t.deleteRecursive(n.Storage, key, keyStart, preserveAccountNode, n.Incarnation)
if updated {
- n.storage = nn
- n.rootCorrect = false
+ n.Storage = nn
+ n.RootCorrect = false
}
newNode = n
return
@@ -1065,7 +1272,7 @@ func (t *Trie) deleteRecursive(origNode node, key []byte, keyStart int, preserve
func (t *Trie) DeleteSubtree(keyPrefix []byte) {
hexPrefix := keybytesToHex(keyPrefix)
- _, t.root = t.delete(t.root, hexPrefix, true)
+ _, t.RootNode = t.delete(t.RootNode, hexPrefix, true)
}
@@ -1084,7 +1291,7 @@ func (t *Trie) Root() []byte { return t.Hash().Bytes() }
// database and can be used even if the trie doesn't have one.
// DESCRIBED: docs/programmers_guide/guide.md#root
func (t *Trie) Hash() libcommon.Hash {
- if t == nil || t.root == nil {
+ if t == nil || t.RootNode == nil {
return EmptyRoot
}
@@ -1092,13 +1299,13 @@ func (t *Trie) Hash() libcommon.Hash {
defer returnHasherToPool(h)
var result libcommon.Hash
- _, _ = h.hash(t.root, true, result[:])
+ _, _ = h.hash(t.RootNode, true, result[:])
return result
}
func (t *Trie) Reset() {
- resetRefs(t.root)
+ resetRefs(t.RootNode)
}
func (t *Trie) getHasher() *hasher {
@@ -1112,20 +1319,20 @@ func (t *Trie) getHasher() *hasher {
// First returned value is `true` if the node with the specified prefix is found.
func (t *Trie) DeepHash(keyPrefix []byte) (bool, libcommon.Hash) {
hexPrefix := keybytesToHex(keyPrefix)
- accNode, gotValue := t.getAccount(t.root, hexPrefix, 0)
+ accNode, gotValue := t.getAccount(t.RootNode, hexPrefix, 0)
if !gotValue {
return false, libcommon.Hash{}
}
- if accNode.rootCorrect {
+ if accNode.RootCorrect {
return true, accNode.Root
}
- if accNode.storage == nil {
+ if accNode.Storage == nil {
accNode.Root = EmptyRoot
- accNode.rootCorrect = true
+ accNode.RootCorrect = true
} else {
h := t.getHasher()
defer returnHasherToPool(h)
- h.hash(accNode.storage, true, accNode.Root[:])
+ h.hash(accNode.Storage, true, accNode.Root[:])
}
return true, accNode.Root
}
@@ -1140,14 +1347,14 @@ func (t *Trie) EvictNode(hex []byte) {
if !ok {
return
}
- if accNode, ok := parent.(*accountNode); isCode && ok {
+ if accNode, ok := parent.(*AccountNode); isCode && ok {
// add special treatment to code nodes
- accNode.code = nil
+ accNode.Code = nil
return
}
switch nd.(type) {
- case valueNode, hashNode:
+ case ValueNode, *HashNode:
return
default:
// can work with other nodes type
@@ -1159,16 +1366,16 @@ func (t *Trie) EvictNode(hex []byte) {
return
}
copy(hn[:], nd.reference())
- hnode := hashNode{hash: hn[:]}
+ hnode := &HashNode{hash: hn[:]}
t.notifyUnloadRecursive(hex, incarnation, nd)
switch p := parent.(type) {
case nil:
- t.root = hnode
- case *shortNode:
+ t.RootNode = hnode
+ case *ShortNode:
p.Val = hnode
- case *duoNode:
+ case *DuoNode:
i1, i2 := p.childrenIdx()
switch hex[len(hex)-1] {
case i1:
@@ -1176,41 +1383,41 @@ func (t *Trie) EvictNode(hex []byte) {
case i2:
p.child2 = hnode
}
- case *fullNode:
+ case *FullNode:
idx := hex[len(hex)-1]
p.Children[idx] = hnode
- case *accountNode:
- p.storage = hnode
+ case *AccountNode:
+ p.Storage = hnode
}
}
-func (t *Trie) notifyUnloadRecursive(hex []byte, incarnation uint64, nd node) {
+func (t *Trie) notifyUnloadRecursive(hex []byte, incarnation uint64, nd Node) {
switch n := nd.(type) {
- case *shortNode:
+ case *ShortNode:
hex = append(hex, n.Key...)
if hex[len(hex)-1] == 16 {
hex = hex[:len(hex)-1]
}
t.notifyUnloadRecursive(hex, incarnation, n.Val)
- case *accountNode:
- if n.storage == nil {
+ case *AccountNode:
+ if n.Storage == nil {
return
}
- if _, ok := n.storage.(hashNode); ok {
+ if _, ok := n.Storage.(*HashNode); ok {
return
}
- t.notifyUnloadRecursive(hex, n.Incarnation, n.storage)
- case *fullNode:
+ t.notifyUnloadRecursive(hex, n.Incarnation, n.Storage)
+ case *FullNode:
for i := range n.Children {
if n.Children[i] == nil {
continue
}
- if _, ok := n.Children[i].(hashNode); ok {
+ if _, ok := n.Children[i].(*HashNode); ok {
continue
}
t.notifyUnloadRecursive(append(hex, uint8(i)), incarnation, n.Children[i])
}
- case *duoNode:
+ case *DuoNode:
i1, i2 := n.childrenIdx()
if n.child1 != nil {
t.notifyUnloadRecursive(append(hex, i1), incarnation, n.child1)
@@ -1224,9 +1431,9 @@ func (t *Trie) notifyUnloadRecursive(hex []byte, incarnation uint64, nd node) {
}
func (t *Trie) TrieSize() int {
- return calcSubtreeSize(t.root)
+ return calcSubtreeSize(t.RootNode)
}
func (t *Trie) NumberOfAccounts() int {
- return calcSubtreeNodes(t.root)
+ return calcSubtreeNodes(t.RootNode)
}
diff --git a/erigon-lib/trie/trie_from_witness.go b/erigon-lib/trie/trie_from_witness.go
new file mode 100644
index 00000000000..0584cfd210b
--- /dev/null
+++ b/erigon-lib/trie/trie_from_witness.go
@@ -0,0 +1,95 @@
+package trie
+
+import (
+ "fmt"
+
+ "github.com/holiman/uint256"
+
+ "github.com/erigontech/erigon-lib/rlphacks"
+)
+
+func BuildTrieFromWitness(witness *Witness, trace bool) (*Trie, error) {
+ hb := NewHashBuilder(false)
+ for _, operator := range witness.Operators {
+ switch op := operator.(type) {
+ case *OperatorLeafValue:
+ if trace {
+ fmt.Printf("LEAF ")
+ }
+ keyHex := op.Key
+ val := op.Value
+ if err := hb.leaf(len(op.Key), keyHex, rlphacks.RlpSerializableBytes(val)); err != nil {
+ return nil, err
+ }
+ case *OperatorExtension:
+ if trace {
+ fmt.Printf("EXTENSION ")
+ }
+ if err := hb.extension(op.Key); err != nil {
+ return nil, err
+ }
+ case *OperatorBranch:
+ if trace {
+ fmt.Printf("BRANCH ")
+ }
+ if err := hb.branch(uint16(op.Mask)); err != nil {
+ return nil, err
+ }
+ case *OperatorHash:
+ if trace {
+ fmt.Printf("HASH ")
+ }
+ if err := hb.hash(op.Hash[:]); err != nil {
+ return nil, err
+ }
+ case *OperatorCode:
+ if trace {
+ fmt.Printf("CODE ")
+ }
+
+ if err := hb.code(op.Code); err != nil {
+ return nil, err
+ }
+
+ case *OperatorLeafAccount:
+ if trace {
+ fmt.Printf("ACCOUNTLEAF(code=%v storage=%v) ", op.HasCode, op.HasStorage)
+ }
+ balance := uint256.NewInt(0)
+ balance.SetBytes(op.Balance.Bytes())
+ nonce := op.Nonce
+
+ // FIXME: probably not needed, fix hb.accountLeaf
+ fieldSet := uint32(3)
+ if op.HasCode && op.HasStorage {
+ fieldSet = 15
+ }
+
+ // Incarnation is always needed for a hashbuilder.
+ // but it is just our implementation detail needed for contract self-descruction support with our
+ // db structure. Stateless clients don't access the DB so we can just pass 0 here.
+ incarnation := uint64(0)
+
+ if err := hb.accountLeaf(len(op.Key), op.Key, balance, nonce, incarnation, fieldSet, int(op.CodeSize)); err != nil {
+ return nil, err
+ }
+ case *OperatorEmptyRoot:
+ if trace {
+ fmt.Printf("EMPTYROOT ")
+ }
+ hb.emptyRoot()
+ default:
+ return nil, fmt.Errorf("unknown operand type: %T", operator)
+ }
+ }
+ if trace {
+ fmt.Printf("\n")
+ }
+ if !hb.hasRoot() {
+ return New(EmptyRoot), nil
+ }
+ r := hb.root()
+ tr := New(hb.rootHash())
+ tr.RootNode = r
+ return tr, nil
+}
diff --git a/erigon-lib/trie/trie_root.go b/erigon-lib/trie/trie_root.go
index b1694b2bbcc..59cb975c8b4 100644
--- a/erigon-lib/trie/trie_root.go
+++ b/erigon-lib/trie/trie_root.go
@@ -140,7 +140,7 @@ type RootHashAggregator struct {
accData GenStructStepAccountData
// Used to construct an Account proof while calculating the tree root.
- proofRetainer *ProofRetainer
+ proofRetainer ProofRetainer
cutoff bool
}
@@ -176,7 +176,7 @@ func NewFlatDBTrieLoader(logPrefix string, rd RetainDeciderWithMarker, hc HashCo
}
func (l *FlatDBTrieLoader) SetProofRetainer(pr *ProofRetainer) {
- l.receiver.proofRetainer = pr
+ l.receiver.proofRetainer = *pr
}
// CalcTrieRoot algo:
diff --git a/erigon-lib/trie/trie_test.go b/erigon-lib/trie/trie_test.go
index 48ecfdebb76..ba7f649b7ba 100644
--- a/erigon-lib/trie/trie_test.go
+++ b/erigon-lib/trie/trie_test.go
@@ -22,6 +22,7 @@ package trie
import (
"bytes"
"encoding/binary"
+ "encoding/hex"
"fmt"
"math/big"
"math/rand"
@@ -398,7 +399,7 @@ func TestCodeNodeGetHashedAccount(t *testing.T) {
hex := keybytesToHex(crypto.Keccak256(address[:]))
- _, trie.root = trie.insert(trie.root, hex, hashNode{hash: fakeAccountHash[:]})
+ _, trie.RootNode = trie.insert(trie.RootNode, hex, &HashNode{hash: fakeAccountHash[:]})
value, gotValue := trie.GetAccountCode(crypto.Keccak256(address[:]))
assert.False(t, gotValue, "should indicate that account exists but hashed")
@@ -635,3 +636,98 @@ func TestNextSubtreeHex(t *testing.T) {
assert.Equal(tc.expect, res, "%s, %s", tc.prev, tc.next)
}
}
+
+func TestShortNode(t *testing.T) {
+ extensionKeyStr := "0b00000d020809020b080f0d0a090a0a0705070f050d0002090f0d0d0e07080e0402070e010c08030d0e0409060e040b0e0406060b0c080b0503010005"
+ extensionKeyNibbles := make([]byte, len(extensionKeyStr)/2+1)
+ for i := 0; i < len(extensionKeyStr)/2; i++ {
+ c, err := hex.DecodeString(extensionKeyStr[2*i : 2*i+2])
+ if err != nil {
+ t.Errorf("parsing error")
+ }
+ extensionKeyNibbles[i] = c[0]
+ }
+ extensionKeyNibbles[len(extensionKeyNibbles)-1] = 16
+
+ accRlpHex := "f84b08873f54314ab16fd0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
+ accRlp, err := hex.DecodeString(accRlpHex)
+ if err != nil {
+ t.Fatalf("failed to decode rlp from hex")
+ }
+
+ valNode := ValueNode(accRlp)
+
+ shortNode := &ShortNode{Key: extensionKeyNibbles, Val: valNode}
+ trie := NewInMemoryTrieRLPEncoded(shortNode)
+ trie.valueNodesRLPEncoded = true
+ rootHash := trie.Root()
+
+ expectedHashStr := "fa7297cfa8b2d445e356e9f752e23b018ae8717fdf117cbe4fcef1b16217d3c2"
+ expectedHashBytes, err := hex.DecodeString(expectedHashStr)
+ if err != nil {
+ t.Fatalf("unable to decode expected hash %v", err)
+ }
+ if !bytes.Equal(rootHash, expectedHashBytes) {
+ t.Fatalf("rootHash(%x) != expectedHash(%x)", rootHash, expectedHashBytes)
+ }
+}
+
+//func TestIHCursorCanUseNextParent(t *testing.T) {
+// db, assert := ethdb.NewMemDatabase(), require.New(t)
+// defer db.Close()
+// hash := fmt.Sprintf("%064d", 0)
+//
+// ih := AccTrie(nil, nil, nil, nil)
+//
+// ih.k[1], ih.v[1], ih.hasTree[1] = common.FromHex("00"), common.FromHex(hash+hash), 0b0000000000000110
+// ih.k[2], ih.v[2], ih.hasTree[2] = common.FromHex("0001"), common.FromHex(hash), 0b1000000000000000
+// ih.lvl = 2
+// ih.hashID[2] = 1
+// ih.hashID[1] = 0
+// assert.True(ih._nextSiblingOfParentInMem())
+// assert.Equal(ih.k[ih.lvl], common.FromHex("00"))
+//
+// ih.k[1], ih.v[1], ih.hasTree[1] = common.FromHex("00"), common.FromHex(hash+hash), 0b0000000000000110
+// ih.k[3], ih.v[3], ih.hasTree[3] = common.FromHex("000101"), common.FromHex(hash), 0b1000000000000000
+// ih.lvl = 3
+// ih.hashID[3] = 1
+// ih.hashID[1] = 0
+// assert.True(ih._nextSiblingOfParentInMem())
+// assert.Equal(ih.k[ih.lvl], common.FromHex("00"))
+//
+//}
+//
+//func _TestEmptyRoot(t *testing.T) {
+// sc := shards.NewStateCache(32, 64*1024)
+//
+// sc.SetAccountHashesRead(common.FromHex("00"), 0b111, 0b111, 0b111, []libcommon.Hash{{}, {}, {}})
+// sc.SetAccountHashesRead(common.FromHex("01"), 0b111, 0b111, 0b111, []libcommon.Hash{{}, {}, {}})
+// sc.SetAccountHashesRead(common.FromHex("02"), 0b111, 0b111, 0b111, []libcommon.Hash{{}, {}, {}})
+//
+// rl := NewRetainList(0)
+// rl.AddHex(common.FromHex("01"))
+// rl.AddHex(common.FromHex("0101"))
+// canUse := func(prefix []byte) bool { return !rl.Retain(prefix) }
+// i := 0
+// if err := sc.AccountTree([]byte{}, func(ihK []byte, h libcommon.Hash, hasTree, skipState bool) (toChild bool, err error) {
+// i++
+// switch i {
+// case 1:
+// assert.Equal(t, common.FromHex("0001"), ihK)
+// case 2:
+// assert.Equal(t, common.FromHex("0100"), ihK)
+// case 3:
+// assert.Equal(t, common.FromHex("0102"), ihK)
+// case 4:
+// assert.Equal(t, common.FromHex("0202"), ihK)
+// }
+// if ok := canUse(ihK); ok {
+// return false, nil
+// }
+// return hasTree, nil
+// }, func(cur []byte) {
+// panic(fmt.Errorf("key %x not found in cache", cur))
+// }); err != nil {
+// t.Fatal(err)
+// }
+//}
diff --git a/erigon-lib/trie/trie_witness.go b/erigon-lib/trie/trie_witness.go
new file mode 100644
index 00000000000..59731d55ffa
--- /dev/null
+++ b/erigon-lib/trie/trie_witness.go
@@ -0,0 +1,55 @@
+package trie
+
+import "errors"
+
+func (t *Trie) ExtractWitness(trace bool, rl RetainDecider) (*Witness, error) {
+ var rd RetainDecider
+ if rl != nil {
+ rd = rl
+ }
+ return extractWitnessFromRootNode(t.RootNode, trace, rd)
+}
+
+func (t *Trie) ExtractWitnessForPrefix(prefix []byte, trace bool, rl RetainDecider) (*Witness, error) {
+ foundNode, _, found, _ := t.getNode(prefix, false)
+ if !found {
+ return nil, errors.New("no data found for given prefix")
+ }
+ return extractWitnessFromRootNode(foundNode, trace, rl)
+}
+
+// ExtractWitnesses extracts witnesses for subtries starting from the specified root
+// if retainDec param is nil it will make a witness for the full subtrie,
+// if retainDec param is set to a RetainList instance, it will make a witness for only the accounts/storages that were actually touched; other paths will be hashed.
+func ExtractWitnesses(subTries SubTries, trace bool, retainDec RetainDecider) ([]*Witness, error) {
+ var witnesses []*Witness
+ for _, root := range subTries.roots {
+ builder := NewWitnessBuilder(root, trace)
+ var limiter *MerklePathLimiter = nil
+ if retainDec != nil {
+ hr := newHasher(false)
+ defer returnHasherToPool(hr)
+ limiter = &MerklePathLimiter{retainDec, hr.hash}
+ }
+ if witness, err := builder.Build(limiter); err == nil {
+ witnesses = append(witnesses, witness)
+ } else {
+ return witnesses, err
+ }
+ }
+ return witnesses, nil
+}
+
+// extractWitnessFromRootNode extracts witness for subtrie starting from the specified root
+// if retainDec param is nil it will make a witness for the full subtrie,
+// if retainDec param is set to a RetainList instance, it will make a witness for only the accounts/storages that were actually touched; other paths will be hashed.
+func extractWitnessFromRootNode(root Node, trace bool, retainDec RetainDecider) (*Witness, error) {
+ builder := NewWitnessBuilder(root, trace)
+ var limiter *MerklePathLimiter = nil
+ if retainDec != nil {
+ hr := newHasher(false)
+ defer returnHasherToPool(hr)
+ limiter = &MerklePathLimiter{retainDec, hr.hash}
+ }
+ return builder.Build(limiter)
+}
diff --git a/erigon-lib/trie/witness.go b/erigon-lib/trie/witness.go
new file mode 100644
index 00000000000..22005d9677d
--- /dev/null
+++ b/erigon-lib/trie/witness.go
@@ -0,0 +1,238 @@
+package trie
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// WitnessStorage is an interface representing a single
+type WitnessStorage interface {
+ GetWitnessesForBlock(uint64, uint32) ([]byte, error)
+}
+
+// WitnessVersion represents the current version of the block witness
+// in case of incompatible changes it should be updated and the code to migrate the
+// old witness format should be present
+const WitnessVersion = uint8(0)
+
+// WitnessHeader contains version information and maybe some future format bits
+// the version is always the 1st bit.
+type WitnessHeader struct {
+ Version uint8
+}
+
+func (h *WitnessHeader) WriteTo(out *OperatorMarshaller) error {
+ _, err := out.WithColumn(ColumnStructure).Write([]byte{h.Version})
+ return err
+}
+
+func (h *WitnessHeader) LoadFrom(input io.Reader) error {
+ version := make([]byte, 1)
+ if _, err := input.Read(version); err != nil {
+ return err
+ }
+
+ h.Version = version[0]
+ return nil
+}
+
+func defaultWitnessHeader() WitnessHeader {
+ return WitnessHeader{WitnessVersion}
+}
+
+type Witness struct {
+ Header WitnessHeader
+ Operators []WitnessOperator
+}
+
+func NewWitness(operands []WitnessOperator) *Witness {
+ return &Witness{
+ Header: defaultWitnessHeader(),
+ Operators: operands,
+ }
+}
+
+func (w *Witness) WriteInto(out io.Writer) (*BlockWitnessStats, error) {
+ statsCollector := NewOperatorMarshaller(out)
+
+ if err := w.Header.WriteTo(statsCollector); err != nil {
+ return nil, err
+ }
+
+ for _, op := range w.Operators {
+ if err := op.WriteTo(statsCollector); err != nil {
+ return nil, err
+ }
+ }
+ return statsCollector.GetStats(), nil
+}
+
+func NewWitnessFromReader(input io.Reader, trace bool) (*Witness, error) {
+ var header WitnessHeader
+ if err := header.LoadFrom(input); err != nil {
+ return nil, err
+ }
+
+ if header.Version != WitnessVersion {
+ return nil, fmt.Errorf("unexpected witness version: expected %d, got %d", WitnessVersion, header.Version)
+ }
+
+ operatorLoader := NewOperatorUnmarshaller(input)
+
+ opcode := make([]byte, 1)
+ var err error
+ operands := make([]WitnessOperator, 0)
+ for _, err = input.Read(opcode); ; _, err = input.Read(opcode) {
+ if errors.Is(err, io.EOF) {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+ var op WitnessOperator
+ switch OperatorKindCode(opcode[0]) {
+ case OpHash:
+ op = &OperatorHash{}
+ case OpLeaf:
+ op = &OperatorLeafValue{}
+ case OpAccountLeaf:
+ op = &OperatorLeafAccount{}
+ case OpCode:
+ op = &OperatorCode{}
+ case OpBranch:
+ op = &OperatorBranch{}
+ case OpEmptyRoot:
+ op = &OperatorEmptyRoot{}
+ case OpExtension:
+ op = &OperatorExtension{}
+ case OpNewTrie:
+ /* end of the current trie, end the function */
+ default:
+ return nil, fmt.Errorf("unexpected opcode while reading witness: %x", opcode[0])
+ }
+
+ if op == nil {
+ break
+ }
+
+ err = op.LoadFrom(operatorLoader)
+ if err != nil {
+ return nil, err
+ }
+
+ if trace {
+ fmt.Printf("read op %T -> %+v\n", op, op)
+ }
+
+ operands = append(operands, op)
+ }
+ if trace {
+ fmt.Println("end of read ***** ")
+ }
+ if err != nil && !errors.Is(err, io.EOF) {
+ return nil, err
+ }
+
+ return &Witness{Header: header, Operators: operands}, nil
+}
+
+func (w *Witness) WriteDiff(w2 *Witness, output io.Writer) {
+ if w.Header.Version != w2.Header.Version {
+ fmt.Fprintf(output, "w1 header %d; w2 header %d\n", w.Header.Version, w2.Header.Version)
+ }
+
+ if len(w.Operators) != len(w2.Operators) {
+ fmt.Fprintf(output, "w1 operands: %d; w2 operands: %d\n", len(w.Operators), len(w2.Operators))
+ }
+
+ length := len(w.Operators)
+ if len(w2.Operators) > length {
+ length = len(w2.Operators)
+ }
+
+ for i := 0; i < length; i++ {
+ var op WitnessOperator
+ if i < len(w.Operators) {
+ op = w.Operators[i]
+ }
+ if i >= len(w2.Operators) {
+ fmt.Fprintf(output, "unexpected o1[%d] = %T %v; o2[%d] = nil\n", i, op, op, i)
+ continue
+ }
+ switch o1 := op.(type) {
+ case *OperatorBranch:
+ o2, ok := w2.Operators[i].(*OperatorBranch)
+ if !ok {
+ fmt.Fprintf(output, "o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ if o1.Mask != o2.Mask {
+ fmt.Fprintf(output, "o1[%d].Mask = %v; o2[%d].Mask = %v", i, o1.Mask, i, o2.Mask)
+ }
+ case *OperatorHash:
+ o2, ok := w2.Operators[i].(*OperatorHash)
+ if !ok {
+ fmt.Fprintf(output, "o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ if !bytes.Equal(o1.Hash.Bytes(), o2.Hash.Bytes()) {
+ fmt.Fprintf(output, "o1[%d].Hash = %s; o2[%d].Hash = %s\n", i, o1.Hash.Hex(), i, o2.Hash.Hex())
+ }
+ case *OperatorCode:
+ o2, ok := w2.Operators[i].(*OperatorCode)
+ if !ok {
+ fmt.Fprintf(output, "o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ if !bytes.Equal(o1.Code, o2.Code) {
+ fmt.Fprintf(output, "o1[%d].Code = %x; o2[%d].Code = %x\n", i, o1.Code, i, o2.Code)
+ }
+ case *OperatorEmptyRoot:
+ o2, ok := w2.Operators[i].(*OperatorEmptyRoot)
+ if !ok {
+ fmt.Fprintf(output, "o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ case *OperatorExtension:
+ o2, ok := w2.Operators[i].(*OperatorExtension)
+ if !ok {
+ fmt.Fprintf(output, "o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ if !bytes.Equal(o1.Key, o2.Key) {
+ fmt.Fprintf(output, "extension o1[%d].Key = %x; o2[%d].Key = %x\n", i, o1.Key, i, o2.Key)
+ }
+ case *OperatorLeafAccount:
+ o2, ok := w2.Operators[i].(*OperatorLeafAccount)
+ if !ok {
+ fmt.Fprintf(output, "o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ if !bytes.Equal(o1.Key, o2.Key) {
+ fmt.Fprintf(output, "leafAcc o1[%d].Key = %x; o2[%d].Key = %x\n", i, o1.Key, i, o2.Key)
+ }
+ if o1.Nonce != o2.Nonce {
+ fmt.Fprintf(output, "leafAcc o1[%d].Nonce = %v; o2[%d].Nonce = %v\n", i, o1.Nonce, i, o2.Nonce)
+ }
+ if o1.Balance.String() != o2.Balance.String() {
+ fmt.Fprintf(output, "leafAcc o1[%d].Balance = %v; o2[%d].Balance = %v\n", i, o1.Balance.String(), i, o2.Balance.String())
+ }
+ if o1.HasCode != o2.HasCode {
+ fmt.Fprintf(output, "leafAcc o1[%d].HasCode = %v; o2[%d].HasCode = %v\n", i, o1.HasCode, i, o2.HasCode)
+ }
+ if o1.HasStorage != o2.HasStorage {
+ fmt.Fprintf(output, "leafAcc o1[%d].HasStorage = %v; o2[%d].HasStorage = %v\n", i, o1.HasStorage, i, o2.HasStorage)
+ }
+ case *OperatorLeafValue:
+ o2, ok := w2.Operators[i].(*OperatorLeafValue)
+ if !ok {
+ fmt.Fprintf(output, "o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ if !bytes.Equal(o1.Key, o2.Key) {
+ fmt.Fprintf(output, "leafVal o1[%d].Key = %x; o2[%d].Key = %x\n", i, o1.Key, i, o2.Key)
+ }
+ if !bytes.Equal(o1.Value, o2.Value) {
+ fmt.Fprintf(output, "leafVal o1[%d].Value = %x; o2[%d].Value = %x\n", i, o1.Value, i, o2.Value)
+ }
+ default:
+ o2 := w2.Operators[i]
+ fmt.Fprintf(output, "unexpected o1[%d] = %T %+v; o2[%d] = %T %+v\n", i, o1, o1, i, o2, o2)
+ }
+ }
+}
diff --git a/erigon-lib/trie/witness_builder.go b/erigon-lib/trie/witness_builder.go
new file mode 100644
index 00000000000..e14b6425c24
--- /dev/null
+++ b/erigon-lib/trie/witness_builder.go
@@ -0,0 +1,287 @@
+package trie
+
+import (
+ "fmt"
+ "math/big"
+
+ libcommon "github.com/erigontech/erigon-lib/common"
+)
+
+type HashNodeFunc func(Node, bool, []byte) (int, error)
+
+type MerklePathLimiter struct {
+ RetainDecider RetainDecider
+ HashFunc HashNodeFunc
+}
+
+type WitnessBuilder struct {
+ root Node
+ trace bool
+ operands []WitnessOperator
+}
+
+func NewWitnessBuilder(root Node, trace bool) *WitnessBuilder {
+ return &WitnessBuilder{
+ root: root,
+ trace: trace,
+ operands: make([]WitnessOperator, 0),
+ }
+}
+
+func (b *WitnessBuilder) Build(limiter *MerklePathLimiter) (*Witness, error) {
+ err := b.makeBlockWitness(b.root, []byte{}, limiter, true)
+ witness := NewWitness(b.operands)
+ b.operands = nil
+ return witness, err
+}
+
+func (b *WitnessBuilder) addLeafOp(key []byte, value []byte) error {
+ if b.trace {
+ fmt.Printf("LEAF_VALUE: k %x v:%x\n", key, value)
+ }
+
+ var op OperatorLeafValue
+
+ op.Key = make([]byte, len(key))
+ copy(op.Key, key)
+ if value != nil {
+ op.Value = make([]byte, len(value))
+ copy(op.Value, value)
+ }
+
+ b.operands = append(b.operands, &op)
+ return nil
+}
+
+func (b *WitnessBuilder) addAccountLeafOp(key []byte, accountNode *AccountNode, codeSize int) error {
+ if b.trace {
+ fmt.Printf("LEAF_ACCOUNT: k %x acc:%v\n", key, accountNode)
+ }
+
+ var op OperatorLeafAccount
+ op.Key = make([]byte, len(key))
+ copy(op.Key, key)
+
+ op.Nonce = accountNode.Nonce
+ op.Balance = big.NewInt(0)
+ op.Balance.SetBytes(accountNode.Balance.Bytes())
+
+ if !accountNode.IsEmptyRoot() || !accountNode.IsEmptyCodeHash() {
+ op.HasCode = true
+ op.HasStorage = true
+ }
+
+ op.CodeSize = uint64(codeSize)
+
+ b.operands = append(b.operands, &op)
+
+ return nil
+}
+
+func (b *WitnessBuilder) addExtensionOp(key []byte) error {
+ if b.trace {
+ fmt.Printf("EXTENSION: k %x\n", key)
+ }
+
+ var op OperatorExtension
+ op.Key = make([]byte, len(key))
+ copy(op.Key, key)
+
+ b.operands = append(b.operands, &op)
+ return nil
+}
+
+func (b *WitnessBuilder) makeHashNode(n Node, force bool, hashNodeFunc HashNodeFunc) (HashNode, error) {
+ switch n := n.(type) {
+ case HashNode:
+ return n, nil
+ default:
+ var hash libcommon.Hash
+ if _, err := hashNodeFunc(n, force, hash[:]); err != nil {
+ return HashNode{}, err
+ }
+ return HashNode{hash: hash[:]}, nil
+ }
+}
+
+func (b *WitnessBuilder) addHashOp(n *HashNode) error {
+ if b.trace {
+ fmt.Printf("HASH: type: %T v %s\n", n, n)
+ }
+
+ var op OperatorHash
+ op.Hash = libcommon.BytesToHash(n.hash)
+
+ b.operands = append(b.operands, &op)
+ return nil
+}
+
+func (b *WitnessBuilder) addBranchOp(mask uint32) error {
+ if b.trace {
+ fmt.Printf("BRANCH: mask=%b\n", mask)
+ }
+
+ var op OperatorBranch
+ op.Mask = mask
+
+ b.operands = append(b.operands, &op)
+ return nil
+}
+
+func (b *WitnessBuilder) addCodeOp(code []byte) error {
+ if b.trace {
+ fmt.Printf("CODE: len=%d\n", len(code))
+ }
+
+ var op OperatorCode
+ op.Code = make([]byte, len(code))
+ copy(op.Code, code)
+
+ b.operands = append(b.operands, &op)
+ return nil
+}
+
+func (b *WitnessBuilder) addEmptyRoot() error {
+ if b.trace {
+ fmt.Printf("EMPTY ROOT\n")
+ }
+
+ b.operands = append(b.operands, &OperatorEmptyRoot{})
+ return nil
+}
+
+func (b *WitnessBuilder) processAccountCode(n *AccountNode, retainDec RetainDecider) (int, error) {
+ if n.IsEmptyRoot() && n.IsEmptyCodeHash() {
+ return 0, nil
+ }
+
+ if n.Code == nil || (retainDec != nil && !retainDec.IsCodeTouched(n.CodeHash)) {
+ codeSize := n.CodeSize
+ if n.Code != nil {
+ codeSize = len(n.Code)
+ }
+ return codeSize, b.addHashOp(&HashNode{hash: n.CodeHash[:]})
+ }
+
+ return len(n.Code), b.addCodeOp(n.Code)
+}
+
+func (b *WitnessBuilder) processAccountStorage(n *AccountNode, hex []byte, limiter *MerklePathLimiter) error {
+ if n.IsEmptyRoot() && n.IsEmptyCodeHash() {
+ return nil
+ }
+
+ if n.Storage == nil {
+ return b.addEmptyRoot()
+ }
+
+ // Here we substitute rs parameter for storageRs, because it needs to become the default
+ return b.makeBlockWitness(n.Storage, hex, limiter, true)
+}
+
+func (b *WitnessBuilder) makeBlockWitness(
+ nd Node, hex []byte, limiter *MerklePathLimiter, force bool) error {
+
+ processAccountNode := func(key []byte, storageKey []byte, n *AccountNode) error {
+ var retainDec RetainDecider
+ if limiter != nil {
+ retainDec = limiter.RetainDecider
+ }
+ var codeSize int
+ var err error
+ if codeSize, err = b.processAccountCode(n, retainDec); err != nil {
+ return err
+ }
+ if err := b.processAccountStorage(n, storageKey, limiter); err != nil {
+ return err
+ }
+ return b.addAccountLeafOp(key, n, codeSize)
+ }
+
+ switch n := nd.(type) {
+ case nil:
+ return nil
+ case ValueNode:
+ return b.addLeafOp(hex, n)
+ case *AccountNode:
+ return processAccountNode(hex, hex, n)
+ case *ShortNode:
+ h := n.Key
+ // Remove terminator
+ if h[len(h)-1] == 16 {
+ h = h[:len(h)-1]
+ }
+ hexVal := concat(hex, h...)
+ switch v := n.Val.(type) {
+ case ValueNode:
+ return b.addLeafOp(n.Key, v[:])
+ case *AccountNode:
+ return processAccountNode(n.Key, hexVal, v)
+ default:
+ if err := b.makeBlockWitness(n.Val, hexVal, limiter, false); err != nil {
+ return err
+ }
+
+ return b.addExtensionOp(n.Key)
+ }
+ case *DuoNode:
+ hashOnly := limiter != nil && !limiter.RetainDecider.Retain(hex) // Save this because rl can move on to other keys during the recursive invocation
+ if b.trace {
+ fmt.Printf("b.retainDec.Retain(%x) -> %v\n", hex, !hashOnly)
+ }
+ if hashOnly {
+ hn, err := b.makeHashNode(n, force, limiter.HashFunc)
+ if err != nil {
+ return err
+ }
+ return b.addHashOp(&hn)
+ }
+
+ i1, i2 := n.childrenIdx()
+
+ if err := b.makeBlockWitness(n.child1, expandKeyHex(hex, i1), limiter, false); err != nil {
+ return err
+ }
+ if err := b.makeBlockWitness(n.child2, expandKeyHex(hex, i2), limiter, false); err != nil {
+ return err
+ }
+ return b.addBranchOp(n.mask)
+
+ case *FullNode:
+ hashOnly := limiter != nil && !limiter.RetainDecider.Retain(hex) // Save this because rs can move on to other keys during the recursive invocation
+ if hashOnly {
+ hn, err := b.makeHashNode(n, force, limiter.HashFunc)
+ if err != nil {
+ return err
+ }
+ return b.addHashOp(&hn)
+ }
+
+ var mask uint32
+ for i, child := range n.Children {
+ if child != nil {
+ if err := b.makeBlockWitness(child, expandKeyHex(hex, byte(i)), limiter, false); err != nil {
+ return err
+ }
+ mask |= uint32(1) << uint(i)
+ }
+ }
+ return b.addBranchOp(mask)
+
+ case *HashNode:
+ hashOnly := limiter == nil || !limiter.RetainDecider.Retain(hex)
+ if hashOnly {
+ return b.addHashOp(n)
+ }
+ return fmt.Errorf("unexpected hashNode: %s, at hex: %x, (%d), hashOnly: %t", n, hex, len(hex), hashOnly)
+ default:
+ return fmt.Errorf("unexpected node type: %T", nd)
+ }
+}
+
+func expandKeyHex(hex []byte, nibble byte) []byte {
+ result := make([]byte, len(hex)+1)
+ copy(result, hex)
+ result[len(hex)] = nibble
+ return result
+}
diff --git a/erigon-lib/trie/witness_builder_test.go b/erigon-lib/trie/witness_builder_test.go
new file mode 100644
index 00000000000..5a83c44a044
--- /dev/null
+++ b/erigon-lib/trie/witness_builder_test.go
@@ -0,0 +1,80 @@
+package trie
+
+import (
+ "bytes"
+ "testing"
+
+ libcommon "github.com/erigontech/erigon-lib/common"
+
+ "github.com/erigontech/erigon-lib/types/accounts"
+)
+
+func TestBlockWitness(t *testing.T) {
+ tr := New(libcommon.Hash{})
+ tr.Update([]byte("ABCD0001"), []byte("val1"))
+ tr.Update([]byte("ABCE0002"), []byte("val2"))
+
+ rl := NewRetainList(2)
+ rl.AddKey([]byte("ABCD0001"))
+
+ bwb := NewWitnessBuilder(tr.RootNode, false)
+
+ hr := newHasher(false)
+ defer returnHasherToPool(hr)
+
+ var w *Witness
+ var err error
+ if w, err = bwb.Build(&MerklePathLimiter{rl, hr.hash}); err != nil {
+ t.Errorf("Could not make block witness: %v", err)
+ }
+
+ tr1, err := BuildTrieFromWitness(w, false)
+ if err != nil {
+ t.Errorf("Could not restore trie from the block witness: %v", err)
+ }
+ if tr.Hash() != tr1.Hash() {
+ t.Errorf("Reconstructed block witness has different root hash than source trie")
+ }
+
+ expected := []byte("val1")
+ got, _ := tr1.Get([]byte("ABCD0001"))
+ if !bytes.Equal(got, expected) {
+ t.Errorf("unexpected value: %x (expected %x)", got, expected)
+ }
+}
+
+func TestBlockWitnessAccount(t *testing.T) {
+ tr := New(libcommon.Hash{})
+
+ account := accounts.NewAccount()
+ account.Balance.SetUint64(1 * 1000 * 1000)
+
+ tr.UpdateAccount([]byte("ABCD0001"), &account)
+
+ rl := NewRetainList(2)
+ rl.AddKey([]byte("ABCD0001"))
+
+ bwb := NewWitnessBuilder(tr.RootNode, false)
+
+ hr := newHasher(false)
+ defer returnHasherToPool(hr)
+
+ var w *Witness
+ var err error
+ if w, err = bwb.Build(&MerklePathLimiter{rl, hr.hash}); err != nil {
+ t.Errorf("Could not make block witness: %v", err)
+ }
+
+ trBin1, err := BuildTrieFromWitness(w, false)
+ if err != nil {
+ t.Errorf("Could not restore trie from the block witness: %v", err)
+ }
+ if tr.Hash() != trBin1.Hash() {
+ t.Errorf("Reconstructed block witness has different root hash than source trie")
+ }
+
+ got, _ := trBin1.GetAccount([]byte("ABCD0001"))
+ if !account.Equals(got) {
+ t.Errorf("received account is not equal to the initial one")
+ }
+}
diff --git a/erigon-lib/trie/witness_marshalling.go b/erigon-lib/trie/witness_marshalling.go
new file mode 100644
index 00000000000..b1642e5b358
--- /dev/null
+++ b/erigon-lib/trie/witness_marshalling.go
@@ -0,0 +1,224 @@
+package trie
+
+import (
+ "fmt"
+ "io"
+
+ libcommon "github.com/erigontech/erigon-lib/common"
+ "github.com/ugorji/go/codec"
+)
+
+var cbor codec.CborHandle
+
+// OperatorMarshaller provides all needed primitives to read witness operators from a serialized form.
+type OperatorUnmarshaller struct {
+ reader io.Reader
+ decoder *codec.Decoder
+}
+
+func NewOperatorUnmarshaller(r io.Reader) *OperatorUnmarshaller {
+ return &OperatorUnmarshaller{r, codec.NewDecoder(r, &cbor)}
+}
+
+func (l *OperatorUnmarshaller) ReadByteArray() ([]byte, error) {
+ var buffer []byte
+ err := l.decoder.Decode(&buffer)
+ if err != nil {
+ return []byte{}, err
+ }
+
+ return buffer, nil
+}
+
+func (l *OperatorUnmarshaller) ReadHash() (libcommon.Hash, error) {
+ var hash libcommon.Hash
+ bytesRead, err := l.reader.Read(hash[:])
+ if err != nil {
+ return hash, err
+ }
+ if bytesRead != len(hash) {
+ return hash, fmt.Errorf("error while reading hash from input. expected to read %d bytes, read only %d", len(hash), bytesRead)
+ }
+ return hash, nil
+}
+
+func (l *OperatorUnmarshaller) ReadUint32() (uint32, error) {
+ var value uint32
+ if err := l.decoder.Decode(&value); err != nil {
+ return 0, err
+ }
+ return value, nil
+}
+
+func (l *OperatorUnmarshaller) ReadByte() (byte, error) {
+ values := make([]byte, 1)
+ bytesRead, err := l.reader.Read(values)
+ if err != nil {
+ return 0, err
+ }
+ if bytesRead < 1 {
+ return 0, fmt.Errorf("could not read a byte from a reader")
+ }
+ return values[0], nil
+}
+
+func (l *OperatorUnmarshaller) ReadKey() ([]byte, error) {
+ b, err := l.ReadByteArray()
+ if err != nil {
+ return nil, err
+ }
+ return keyBytesToNibbles(b), nil
+}
+
+func (l *OperatorUnmarshaller) ReadUInt64() (uint64, error) {
+ var value uint64
+ err := l.decoder.Decode(&value)
+ if err != nil {
+ return 0, err
+ }
+ return value, nil
+
+}
+
+// OperatorMarshaller is responsible for encoding operators to a stream
+// and collecting stats
+// IMPORTANT: not thread-safe! use from a single thread only
+type OperatorMarshaller struct {
+ currentColumn StatsColumn
+ encoder *codec.Encoder
+ w io.Writer
+ stats map[StatsColumn]uint64
+ total uint64
+}
+
+func NewOperatorMarshaller(w io.Writer) *OperatorMarshaller {
+ marshaller := &OperatorMarshaller{w: w, stats: make(map[StatsColumn]uint64)}
+ // so we can collect stats
+ marshaller.encoder = codec.NewEncoder(marshaller, &cbor)
+ return marshaller
+}
+
+func (w *OperatorMarshaller) WriteOpCode(opcode OperatorKindCode) error {
+ w.WithColumn(ColumnStructure)
+ _, err := w.Write([]byte{byte(opcode)})
+ return err
+}
+
+func (w *OperatorMarshaller) WriteKey(keyNibbles []byte) error {
+ w.WithColumn(ColumnLeafKeys)
+ return w.encoder.Encode(keyNibblesToBytes(keyNibbles))
+}
+
+func (w *OperatorMarshaller) WriteByteValue(value byte) error {
+ w.WithColumn(ColumnLeafValues)
+ _, err := w.Write([]byte{value})
+ return err
+}
+
+func (w *OperatorMarshaller) WriteUint64Value(value uint64) error {
+ w.WithColumn(ColumnLeafValues)
+ return w.encoder.Encode(value)
+}
+
+func (w *OperatorMarshaller) WriteByteArrayValue(value []byte) error {
+ w.WithColumn(ColumnLeafValues)
+ return w.encoder.Encode(value)
+}
+
+func (w *OperatorMarshaller) WriteCode(value []byte) error {
+ w.WithColumn(ColumnCodes)
+ return w.encoder.Encode(value)
+}
+
+func (w *OperatorMarshaller) WriteHash(hash libcommon.Hash) error {
+ w.WithColumn(ColumnHashes)
+ _, err := w.Write(hash[:])
+ return err
+}
+
+func (w *OperatorMarshaller) Write(p []byte) (int, error) {
+ val := w.stats[w.currentColumn]
+
+ written, err := w.w.Write(p)
+
+ val += uint64(written)
+ w.total += uint64(written)
+
+ w.stats[w.currentColumn] = val
+
+ return written, err
+}
+
+func (w *OperatorMarshaller) WithColumn(column StatsColumn) *OperatorMarshaller {
+ w.currentColumn = column
+ return w
+}
+
+func (w *OperatorMarshaller) GetStats() *BlockWitnessStats {
+ return &BlockWitnessStats{
+ witnessSize: w.total,
+ stats: w.stats,
+ }
+}
+
+func keyNibblesToBytes(nibbles []byte) []byte {
+ if len(nibbles) < 1 {
+ return []byte{}
+ }
+ if len(nibbles) < 2 {
+ return nibbles
+ }
+ hasTerminator := false
+ if nibbles[len(nibbles)-1] == 0x10 {
+ nibbles = nibbles[:len(nibbles)-1]
+ hasTerminator = true
+ }
+
+ targetLen := len(nibbles)/2 + len(nibbles)%2 + 1
+
+ result := make([]byte, targetLen)
+ nibbleIndex := 0
+ result[0] = byte(len(nibbles) % 2) // parity bit
+ for i := 1; i < len(result); i++ {
+ result[i] = nibbles[nibbleIndex] * 16
+ nibbleIndex++
+ if nibbleIndex < len(nibbles) {
+ result[i] += nibbles[nibbleIndex]
+ nibbleIndex++
+ }
+ }
+ if hasTerminator {
+ result[0] |= 1 << 1
+ }
+
+ return result
+}
+
+func keyBytesToNibbles(b []byte) []byte {
+ if len(b) < 1 {
+ return []byte{}
+ }
+ if len(b) < 2 {
+ return b
+ }
+
+ hasTerminator := b[0]&(1<<1) != 0
+
+ targetLen := (len(b)-1)*2 - int(b[0]&1)
+
+ nibbles := make([]byte, targetLen)
+
+ nibbleIndex := 0
+ for i := 1; i < len(b); i++ {
+ nibbles[nibbleIndex] = b[i] / 16
+ nibbleIndex++
+ if nibbleIndex < len(nibbles) {
+ nibbles[nibbleIndex] = b[i] % 16
+ nibbleIndex++
+ }
+ }
+ if hasTerminator {
+ return append(nibbles, 0x10)
+ }
+ return nibbles
+}
diff --git a/erigon-lib/trie/witness_operators.go b/erigon-lib/trie/witness_operators.go
new file mode 100644
index 00000000000..a96fcf98196
--- /dev/null
+++ b/erigon-lib/trie/witness_operators.go
@@ -0,0 +1,283 @@
+package trie
+
+import (
+ "math/big"
+
+ libcommon "github.com/erigontech/erigon-lib/common"
+ "github.com/ugorji/go/codec"
+)
+
+const (
+ flagCode = 1 << iota
+ flagStorage
+ flagNonce
+ flagBalance
+)
+
+// OperatorKindCode is "enum" type for defining the opcodes of the stack machine that reconstructs the structure of tries from Structure tape
+type OperatorKindCode uint8
+
+const (
+ // OpLeaf creates leaf node and pushes it onto the node stack, its hash onto the hash stack
+ OpLeaf OperatorKindCode = iota
+ // OpExtension pops a node from the node stack, constructs extension node from it and its operand's key, and pushes this extension node onto
+ // the node stack, its hash onto the hash stack
+ OpExtension
+ // OpBranch has operand, which is a bitset representing digits in the branch node. Pops the children nodes from the node stack (the number of
+ // children is equal to the number of bits in the bitset), constructs branch node and pushes it onto the node stack, its hash onto the hash stack
+ OpBranch
+ // OpHash and pushes the hash them onto the stack.
+ OpHash
+ // OpCode constructs code node and pushes it onto the node stack, its hash onto the hash stack.
+ OpCode
+ // OpAccountLeaf constructs an account node (without any storage and code) and pushes it onto the node stack, its hash onto the hash stack.
+ OpAccountLeaf
+ // OpEmptyRoot places nil onto the node stack, and empty root hash onto the hash stack.
+ OpEmptyRoot
+
+ // OpNewTrie stops the processing, because another trie is encoded into the witness.
+ OpNewTrie = OperatorKindCode(0xBB)
+)
+
+// WitnessOperator is a single operand in the block witness. It knows how to serialize/deserialize itself.
+type WitnessOperator interface {
+ WriteTo(*OperatorMarshaller) error
+
+ // LoadFrom always assumes that the opcode value was already read
+ LoadFrom(*OperatorUnmarshaller) error
+}
+
+type OperatorHash struct {
+ Hash libcommon.Hash
+}
+
+func (o *OperatorHash) WriteTo(output *OperatorMarshaller) error {
+ if err := output.WriteOpCode(OpHash); err != nil {
+ return err
+ }
+ return output.WriteHash(o.Hash)
+}
+
+func (o *OperatorHash) LoadFrom(loader *OperatorUnmarshaller) error {
+ hash, err := loader.ReadHash()
+ if err != nil {
+ return err
+ }
+
+ o.Hash = hash
+ return nil
+}
+
+type OperatorLeafValue struct {
+ Key []byte
+ Value []byte
+}
+
+func (o *OperatorLeafValue) WriteTo(output *OperatorMarshaller) error {
+ if err := output.WriteOpCode(OpLeaf); err != nil {
+ return err
+ }
+
+ if err := output.WriteKey(o.Key); err != nil {
+ return err
+ }
+
+ return output.WriteByteArrayValue(o.Value)
+}
+
+func (o *OperatorLeafValue) LoadFrom(loader *OperatorUnmarshaller) error {
+ key, err := loader.ReadKey()
+ if err != nil {
+ return err
+ }
+
+ o.Key = key
+
+ value, err := loader.ReadByteArray()
+ if err != nil {
+ return err
+ }
+
+ o.Value = value
+ return nil
+}
+
+type OperatorLeafAccount struct {
+ Key []byte
+ Nonce uint64
+ Balance *big.Int
+ HasCode bool
+ HasStorage bool
+ CodeSize uint64
+}
+
+func (o *OperatorLeafAccount) WriteTo(output *OperatorMarshaller) error {
+ if err := output.WriteOpCode(OpAccountLeaf); err != nil {
+ return err
+ }
+
+ if err := output.WriteKey(o.Key); err != nil {
+ return err
+ }
+
+ flags := byte(0)
+ if o.HasCode {
+ flags |= flagCode
+ }
+ if o.HasStorage {
+ flags |= flagStorage
+ }
+ if o.Nonce > 0 {
+ flags |= flagNonce
+ }
+
+ if o.Balance.Sign() != 0 {
+ flags |= flagBalance
+ }
+
+ if err := output.WriteByteValue(flags); err != nil {
+ return err
+ }
+
+ if o.Nonce > 0 {
+ if err := output.WriteUint64Value(o.Nonce); err != nil {
+ return err
+ }
+ }
+
+ if o.Balance.Sign() != 0 {
+ if err := output.WriteByteArrayValue(o.Balance.Bytes()); err != nil {
+ return err
+ }
+ }
+
+ if o.HasCode {
+ if err := output.WriteUint64Value(o.CodeSize); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (o *OperatorLeafAccount) LoadFrom(loader *OperatorUnmarshaller) error {
+ key, err := loader.ReadKey()
+ if err != nil {
+ return err
+ }
+ o.Key = key
+
+ flags, err := loader.ReadByte()
+ if err != nil {
+ return err
+ }
+
+ o.HasCode = flags&flagCode != 0
+ o.HasStorage = flags&flagStorage != 0
+
+ if flags&flagNonce != 0 {
+ o.Nonce, err = loader.ReadUInt64()
+ if err != nil {
+ return err
+ }
+ }
+
+ balance := big.NewInt(0)
+
+ if flags&flagBalance != 0 {
+ var balanceBytes []byte
+ balanceBytes, err = loader.ReadByteArray()
+ if err != nil {
+ return err
+ }
+ balance.SetBytes(balanceBytes)
+ }
+
+ o.Balance = balance
+
+ if o.HasCode {
+ if codeSize, err := loader.ReadUInt64(); err == nil {
+ o.CodeSize = codeSize
+ } else {
+ return err
+ }
+ }
+
+ return nil
+}
+
+type OperatorCode struct {
+ Code []byte
+}
+
+func (o *OperatorCode) WriteTo(output *OperatorMarshaller) error {
+ if err := output.WriteOpCode(OpCode); err != nil {
+ return err
+ }
+
+ return output.WriteCode(o.Code)
+}
+
+func (o *OperatorCode) LoadFrom(loader *OperatorUnmarshaller) error {
+ code, err := loader.ReadByteArray()
+ if err != nil {
+ return err
+ }
+ o.Code = code
+ return nil
+}
+
+type OperatorBranch struct {
+ Mask uint32
+}
+
+func (o *OperatorBranch) WriteTo(output *OperatorMarshaller) error {
+ if err := output.WriteOpCode(OpBranch); err != nil {
+ return err
+ }
+
+ encoder := codec.NewEncoder(output.WithColumn(ColumnStructure), &cbor)
+ return encoder.Encode(o.Mask)
+}
+
+func (o *OperatorBranch) LoadFrom(loader *OperatorUnmarshaller) error {
+ mask, err := loader.ReadUint32()
+ if err != nil {
+ return err
+ }
+
+ o.Mask = mask
+ return nil
+}
+
+type OperatorEmptyRoot struct{}
+
+func (o *OperatorEmptyRoot) WriteTo(output *OperatorMarshaller) error {
+ return output.WriteOpCode(OpEmptyRoot)
+}
+
+func (o *OperatorEmptyRoot) LoadFrom(loader *OperatorUnmarshaller) error {
+ // no-op
+ return nil
+}
+
+type OperatorExtension struct {
+ Key []byte
+}
+
+func (o *OperatorExtension) WriteTo(output *OperatorMarshaller) error {
+ if err := output.WriteOpCode(OpExtension); err != nil {
+ return err
+ }
+ return output.WriteKey(o.Key)
+}
+
+func (o *OperatorExtension) LoadFrom(loader *OperatorUnmarshaller) error {
+ key, err := loader.ReadKey()
+ if err != nil {
+ return err
+ }
+ o.Key = key
+
+ return nil
+}
diff --git a/erigon-lib/trie/witness_operators_test.go b/erigon-lib/trie/witness_operators_test.go
new file mode 100644
index 00000000000..aec67539e93
--- /dev/null
+++ b/erigon-lib/trie/witness_operators_test.go
@@ -0,0 +1,263 @@
+package trie
+
+import (
+ "bytes"
+ "math/big"
+ "testing"
+
+ "github.com/ugorji/go/codec"
+)
+
+func TestOperatoLoaderByteArray(t *testing.T) {
+
+ var cbor codec.CborHandle
+
+ var buffer bytes.Buffer
+
+ encoder := codec.NewEncoder(&buffer, &cbor)
+
+ bytes1 := []byte("test1")
+ bytes2 := []byte("abcd2")
+
+ if err := encoder.Encode(bytes1); err != nil {
+ t.Error(err)
+ }
+
+ if err := encoder.Encode(bytes2); err != nil {
+ t.Error(err)
+ }
+
+ loader1 := NewOperatorUnmarshaller(&buffer)
+
+ decoded1, err := loader1.ReadByteArray()
+ if err != nil {
+ t.Error(err)
+ }
+ if !bytes.Equal(decoded1, bytes1) {
+ t.Errorf("failed to decode bytes, expected %v got %v", bytes1, decoded1)
+ }
+
+ decoded2, err := loader1.ReadByteArray()
+ if err != nil {
+ t.Error(err)
+ }
+ if !bytes.Equal(decoded2, bytes2) {
+ t.Errorf("failed to decode bytes, expected %v got %v", bytes1, decoded1)
+ }
+}
+
+func TestAccountBigBalance(t *testing.T) {
+ key := []byte("l")
+ balance := big.NewInt(0)
+ var ok bool
+ balance, ok = balance.SetString("92233720368547758080", 10)
+ if !ok {
+ t.Error("fail to set balance to a large number")
+ }
+ acc := &OperatorLeafAccount{
+ key,
+ 0,
+ balance,
+ false,
+ false,
+ 0,
+ }
+
+ var buff bytes.Buffer
+
+ collector := NewOperatorMarshaller(&buff)
+
+ err := acc.WriteTo(collector)
+ if err != nil {
+ t.Error(err)
+ }
+
+ // discard the opcode
+ _, err = buff.ReadByte()
+ if err != nil {
+ t.Error(err)
+ }
+
+ acc2 := &OperatorLeafAccount{}
+ loader := NewOperatorUnmarshaller(&buff)
+ if err := acc2.LoadFrom(loader); err != nil {
+ t.Error(err)
+ }
+
+ if acc2.Balance.Cmp(acc.Balance) != 0 {
+ t.Errorf("wrong deserialization of balance (expected: %s got %s)", acc.Balance.String(), acc2.Balance.String())
+ }
+
+}
+
+func TestAccountCompactWriteTo(t *testing.T) {
+ key := []byte("l")
+ acc := &OperatorLeafAccount{
+ key,
+ 0,
+ big.NewInt(0),
+ false,
+ false,
+ 0,
+ }
+
+ var buff bytes.Buffer
+
+ collector := NewOperatorMarshaller(&buff)
+
+ err := acc.WriteTo(collector)
+ if err != nil {
+ t.Error(err)
+ }
+
+ b := buff.Bytes()
+
+ expectedLen := 1 /* opcode */ + 1 /* CBOR prefix for key */ + len(key) + 1 /* flags */
+
+ if len(b) != expectedLen {
+ t.Errorf("unexpected serialization len for default fields, expected %d (no fields seralized), got %d (raw: %v)", expectedLen, len(b), b)
+ }
+}
+
+func TestAccountFullWriteTo(t *testing.T) {
+ key := []byte("l")
+ acc := &OperatorLeafAccount{
+ key,
+ 20,
+ big.NewInt(10),
+ true,
+ true,
+ 0,
+ }
+
+ var buff bytes.Buffer
+
+ collector := NewOperatorMarshaller(&buff)
+
+ err := acc.WriteTo(collector)
+ if err != nil {
+ t.Error(err)
+ }
+
+ b := buff.Bytes()
+
+ compactLen := 1 /* opcode */ + 1 /* CBOR prefix for key */ + len(key) + 1 /* flags */
+
+ if len(b) <= compactLen {
+ t.Errorf("unexpected serialization expected to be bigger than %d (fields seralized), got %d (raw: %v)", compactLen, len(b), b)
+ }
+
+ flags := b[3]
+
+ expectedFlags := byte(0)
+ expectedFlags |= flagStorage
+ expectedFlags |= flagCode
+ expectedFlags |= flagNonce
+ expectedFlags |= flagBalance
+
+ if flags != expectedFlags {
+ t.Errorf("unexpected flags value (expected %b, got %b)", expectedFlags, flags)
+ }
+}
+
+func TestAccountPartialNoNonceWriteTo(t *testing.T) {
+ key := []byte("l")
+ acc := &OperatorLeafAccount{
+ key,
+ 0,
+ big.NewInt(10),
+ true,
+ true,
+ 0,
+ }
+
+ var buff bytes.Buffer
+
+ collector := NewOperatorMarshaller(&buff)
+
+ err := acc.WriteTo(collector)
+ if err != nil {
+ t.Error(err)
+ }
+
+ b := buff.Bytes()
+
+ compactLen := 1 /* opcode */ + 1 /* CBOR prefix for key */ + len(key) + 1 /* flags */
+
+ if len(b) <= compactLen {
+ t.Errorf("unexpected serialization expected to be bigger than %d (fields seralized), got %d (raw: %v)", compactLen, len(b), b)
+ }
+
+ flags := b[3]
+
+ expectedFlags := byte(0)
+ expectedFlags |= flagStorage
+ expectedFlags |= flagCode
+ expectedFlags |= flagBalance
+
+ if flags != expectedFlags {
+ t.Errorf("unexpected flags value (expected %b, got %b)", expectedFlags, flags)
+ }
+}
+
+func TestAccountPartialNoBalanceWriteTo(t *testing.T) {
+ key := []byte("l")
+ acc := &OperatorLeafAccount{
+ key,
+ 22,
+ big.NewInt(0),
+ true,
+ true,
+ 0,
+ }
+
+ var buff bytes.Buffer
+
+ collector := NewOperatorMarshaller(&buff)
+
+ err := acc.WriteTo(collector)
+ if err != nil {
+ t.Error(err)
+ }
+
+ b := buff.Bytes()
+
+ compactLen := 1 /* opcode */ + 1 /* CBOR prefix for key */ + len(key) + 1 /* flags */
+
+ if len(b) <= compactLen {
+ t.Errorf("unexpected serialization expected to be bigger than %d (fields seralized), got %d (raw: %v)", compactLen, len(b), b)
+ }
+
+ flags := b[3]
+
+ expectedFlags := byte(0)
+ expectedFlags |= flagStorage
+ expectedFlags |= flagCode
+ expectedFlags |= flagNonce
+
+ if flags != expectedFlags {
+ t.Errorf("unexpected flags value (expected %b, got %b)", expectedFlags, flags)
+ }
+}
+
+func TestKeySerialization(t *testing.T) {
+ for _, key := range [][]byte{
+ {1, 16},
+ {1, 2, 3, 4, 5},
+ {1, 2, 3, 4, 5, 6},
+ {},
+ {3, 9, 1},
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 15, 15, 15, 15},
+ {1},
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 15, 15, 15, 16},
+ } {
+ b := keyNibblesToBytes(key)
+
+ key2 := keyBytesToNibbles(b)
+
+ if !bytes.Equal(key, key2) {
+ t.Errorf("wrong deserialization, expected %x got %x", key, key2)
+ }
+
+ }
+}
diff --git a/erigon-lib/trie/witness_stats.go b/erigon-lib/trie/witness_stats.go
new file mode 100644
index 00000000000..da0e5180316
--- /dev/null
+++ b/erigon-lib/trie/witness_stats.go
@@ -0,0 +1,41 @@
+package trie
+
+type StatsColumn string
+
+const (
+ ColumnStructure = StatsColumn("structure")
+ ColumnHashes = StatsColumn("hashes")
+ ColumnCodes = StatsColumn("codes")
+ ColumnLeafKeys = StatsColumn("leaf_keys")
+ ColumnLeafValues = StatsColumn("leaf_values")
+ ColumnTotal = StatsColumn("total_witness_size")
+)
+
+type BlockWitnessStats struct {
+ witnessSize uint64
+ stats map[StatsColumn]uint64
+}
+
+func (s *BlockWitnessStats) BlockWitnessSize() uint64 {
+ return s.witnessSize
+}
+
+func (s *BlockWitnessStats) CodesSize() uint64 {
+ return s.stats[ColumnCodes]
+}
+
+func (s *BlockWitnessStats) LeafKeysSize() uint64 {
+ return s.stats[ColumnLeafKeys]
+}
+
+func (s *BlockWitnessStats) LeafValuesSize() uint64 {
+ return s.stats[ColumnLeafValues]
+}
+
+func (s *BlockWitnessStats) StructureSize() uint64 {
+ return s.stats[ColumnStructure]
+}
+
+func (s *BlockWitnessStats) HashesSize() uint64 {
+ return s.stats[ColumnHashes]
+}
diff --git a/erigon-lib/trie/witness_test.go b/erigon-lib/trie/witness_test.go
new file mode 100644
index 00000000000..8cfbf497605
--- /dev/null
+++ b/erigon-lib/trie/witness_test.go
@@ -0,0 +1,96 @@
+package trie
+
+import (
+ "bytes"
+ "fmt"
+ "math/big"
+ "testing"
+
+ libcommon "github.com/erigontech/erigon-lib/common"
+)
+
+func generateOperands() []WitnessOperator {
+ return []WitnessOperator{
+ &OperatorBranch{Mask: 0xFF},
+ &OperatorEmptyRoot{},
+ &OperatorCode{[]byte("code-operand-1")},
+ &OperatorExtension{[]byte{5, 5, 4, 6, 6, 6}},
+ &OperatorLeafValue{[]byte{5, 5, 4, 3, 2, 1}, []byte("leaf-value-value-1")},
+ &OperatorHash{libcommon.HexToHash("0xabcabcabcabc")},
+ &OperatorLeafAccount{
+ []byte{2, 2, 4, 5, 6},
+ 999,
+ big.NewInt(552),
+ true,
+ false,
+ 10,
+ },
+ &OperatorLeafAccount{
+ []byte{2, 2, 4, 5, 7},
+ 757,
+ big.NewInt(334),
+ true,
+ true,
+ 11,
+ },
+ &OperatorLeafAccount{
+ []byte{2, 2, 4, 5, 8},
+ 333,
+ big.NewInt(11112),
+ false,
+ false,
+ 12,
+ },
+ &OperatorLeafAccount{
+ []byte{2, 2, 4, 5, 9},
+ 0,
+ big.NewInt(0),
+ false,
+ false,
+ 13,
+ },
+ }
+}
+
+func witnessesEqual(w1, w2 *Witness) bool {
+ if w1 == nil {
+ return w2 == nil
+ }
+
+ if w2 == nil {
+ return w1 == nil
+ }
+
+ var buff bytes.Buffer
+
+ w1.WriteDiff(w2, &buff)
+
+ diff := buff.String()
+
+ fmt.Printf("%s", diff)
+
+ return len(diff) == 0
+}
+
+func TestWitnessSerialization(t *testing.T) {
+ expectedHeader := defaultWitnessHeader()
+
+ expectedOperands := generateOperands()
+
+ expectedWitness := Witness{expectedHeader, expectedOperands}
+
+ var buffer bytes.Buffer
+
+ if _, err := expectedWitness.WriteInto(&buffer); err != nil {
+ t.Error(err)
+ }
+
+ decodedWitness, err := NewWitnessFromReader(&buffer, false /* trace */)
+ if err != nil {
+ t.Error(err)
+ }
+
+ if !witnessesEqual(&expectedWitness, decodedWitness) {
+ t.Errorf("witnesses not equal: expected %+v; got %+v", expectedWitness, decodedWitness)
+ }
+}
diff --git a/erigon-lib/types/accounts/account.go b/erigon-lib/types/accounts/account.go
index 4bf92881a27..ce8c9a311aa 100644
--- a/erigon-lib/types/accounts/account.go
+++ b/erigon-lib/types/accounts/account.go
@@ -197,6 +197,13 @@ func (a *Account) EncodeRLP(w io.Writer) error {
return err
}
+// returns the RLP encoding of the account directly as a []byte
+func (a *Account) RLP() []byte {
+ accRlp := make([]byte, a.EncodingLengthForHashing())
+ a.EncodeForHashing(accRlp)
+ return accRlp
+}
+
func (a *Account) EncodeForHashing(buffer []byte) {
balanceBytes := 0
if !a.Balance.LtUint64(128) {
diff --git a/erigon-lib/types/witness/types.go b/erigon-lib/types/witness/types.go
new file mode 100644
index 00000000000..3e4e6aa189b
--- /dev/null
+++ b/erigon-lib/types/witness/types.go
@@ -0,0 +1,16 @@
+package witness
+
+import (
+ libcommon "github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon-lib/types/accounts"
+)
+
+type AccountWithAddress struct {
+ Address libcommon.Address
+ Account *accounts.Account
+}
+
+type CodeWithHash struct {
+ Code []byte
+ CodeHash libcommon.Hash
+}
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index 3396a787d1e..a36daa2c1ec 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -90,7 +90,7 @@ var Defaults = Config{
NetworkID: 1,
Prune: prune.DefaultMode,
Miner: params.MiningConfig{
- GasLimit: 30_000_000,
+ GasLimit: 36_000_000,
GasPrice: big.NewInt(params.GWei),
Recommit: 3 * time.Second,
},
diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go
index a37d863d34c..1f493779d15 100644
--- a/eth/ethconfig/gen_config.go
+++ b/eth/ethconfig/gen_config.go
@@ -10,14 +10,13 @@ import (
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/datadir"
"github.com/erigontech/erigon-lib/downloader/downloadercfg"
- "github.com/erigontech/erigon/txnprovider/txpool/txpoolcfg"
- "github.com/erigontech/erigon/cl/beacon/beacon_router_configuration"
"github.com/erigontech/erigon/cl/clparams"
"github.com/erigontech/erigon/consensus/ethash/ethashcfg"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/eth/gasprice/gaspricecfg"
"github.com/erigontech/erigon/ethdb/prune"
"github.com/erigontech/erigon/params"
+ "github.com/erigontech/erigon/txnprovider/txpool/txpoolcfg"
)
// MarshalTOML marshals as TOML.
@@ -32,7 +31,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
BadBlockHash common.Hash
Snapshot BlocksFreezing
Downloader *downloadercfg.Cfg
- BeaconRouter beacon_router_configuration.RouterConfiguration
CaplinConfig clparams.CaplinConfig
Dirs datadir.Dirs
ExternalSnapshotDownloaderAddr string
@@ -55,11 +53,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
PolygonSyncStage bool
Ethstats string
InternalCL bool
- CaplinDiscoveryAddr string
- CaplinDiscoveryPort uint64
- CaplinDiscoveryTCPPort uint64
- SentinelAddr string
- SentinelPort uint64
OverridePragueTime *big.Int `toml:",omitempty"`
SilkwormExecution bool
SilkwormRpcDaemon bool
@@ -85,7 +78,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
enc.BadBlockHash = c.BadBlockHash
enc.Snapshot = c.Snapshot
enc.Downloader = c.Downloader
- enc.CaplinConfig.BeaconAPIRouter = c.CaplinConfig.BeaconAPIRouter
enc.CaplinConfig = c.CaplinConfig
enc.Dirs = c.Dirs
enc.ExternalSnapshotDownloaderAddr = c.ExternalSnapshotDownloaderAddr
@@ -108,11 +100,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
enc.PolygonSyncStage = c.PolygonSyncStage
enc.Ethstats = c.Ethstats
enc.InternalCL = c.InternalCL
- enc.CaplinConfig.CaplinDiscoveryAddr = c.CaplinConfig.CaplinDiscoveryAddr
- enc.CaplinConfig.CaplinDiscoveryPort = c.CaplinConfig.CaplinDiscoveryPort
- enc.CaplinConfig.CaplinDiscoveryTCPPort = c.CaplinConfig.CaplinDiscoveryTCPPort
- enc.CaplinConfig.SentinelAddr = c.CaplinConfig.SentinelAddr
- enc.CaplinConfig.SentinelPort = c.CaplinConfig.SentinelPort
enc.OverridePragueTime = c.OverridePragueTime
enc.SilkwormExecution = c.SilkwormExecution
enc.SilkwormRpcDaemon = c.SilkwormRpcDaemon
@@ -142,7 +129,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
BadBlockHash *common.Hash
Snapshot *BlocksFreezing
Downloader *downloadercfg.Cfg
- BeaconRouter *beacon_router_configuration.RouterConfiguration
CaplinConfig *clparams.CaplinConfig
Dirs *datadir.Dirs
ExternalSnapshotDownloaderAddr *string
@@ -165,11 +151,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
PolygonSyncStage *bool
Ethstats *string
InternalCL *bool
- CaplinDiscoveryAddr *string
- CaplinDiscoveryPort *uint64
- CaplinDiscoveryTCPPort *uint64
- SentinelAddr *string
- SentinelPort *uint64
OverridePragueTime *big.Int `toml:",omitempty"`
SilkwormExecution *bool
SilkwormRpcDaemon *bool
@@ -216,9 +197,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
if dec.Downloader != nil {
c.Downloader = dec.Downloader
}
- if dec.BeaconRouter != nil {
- c.CaplinConfig.BeaconAPIRouter = *dec.BeaconRouter
- }
if dec.CaplinConfig != nil {
c.CaplinConfig = *dec.CaplinConfig
}
@@ -285,21 +263,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
if dec.InternalCL != nil {
c.InternalCL = *dec.InternalCL
}
- if dec.CaplinDiscoveryAddr != nil {
- c.CaplinConfig.CaplinDiscoveryAddr = *dec.CaplinDiscoveryAddr
- }
- if dec.CaplinDiscoveryPort != nil {
- c.CaplinConfig.CaplinDiscoveryPort = *dec.CaplinDiscoveryPort
- }
- if dec.CaplinDiscoveryTCPPort != nil {
- c.CaplinConfig.CaplinDiscoveryTCPPort = *dec.CaplinDiscoveryTCPPort
- }
- if dec.SentinelAddr != nil {
- c.CaplinConfig.SentinelAddr = *dec.SentinelAddr
- }
- if dec.SentinelPort != nil {
- c.CaplinConfig.SentinelPort = *dec.SentinelPort
- }
if dec.OverridePragueTime != nil {
c.OverridePragueTime = dec.OverridePragueTime
}
diff --git a/eth/stagedsync/exec3.go b/eth/stagedsync/exec3.go
index c632b188631..d148f3a249d 100644
--- a/eth/stagedsync/exec3.go
+++ b/eth/stagedsync/exec3.go
@@ -132,6 +132,71 @@ func (p *Progress) Log(suffix string, rs *state.StateV3, in *state.QueueWithRetr
p.prevRepeatCount = repeatCount
}
+// Cases:
+// 1. Snapshots > ExecutionStage: snapshots can have half-block data `10.4`. Get right txNum from SharedDomains (after SeekCommitment)
+// 2. ExecutionStage > Snapshots: no half-block data possible. Rely on DB.
+func restoreTxNum(ctx context.Context, cfg *ExecuteBlockCfg, applyTx kv.Tx, doms *state2.SharedDomains, maxBlockNum uint64) (
+ inputTxNum uint64, maxTxNum uint64, offsetFromBlockBeginning uint64, err error) {
+
+ txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, cfg.blockReader))
+
+ inputTxNum = doms.TxNum()
+
+ if nothing, err := nothingToExec(applyTx, txNumsReader, inputTxNum); err != nil {
+ return 0, 0, 0, err
+ } else if nothing {
+ return 0, 0, 0, err
+ }
+
+ maxTxNum, err = txNumsReader.Max(applyTx, maxBlockNum)
+ if err != nil {
+ return 0, 0, 0, err
+ }
+
+ ok, _blockNum, err := txNumsReader.FindBlockNum(applyTx, doms.TxNum())
+ if err != nil {
+ return 0, 0, 0, err
+ }
+ if !ok {
+ _lb, _lt, _ := txNumsReader.Last(applyTx)
+ _fb, _ft, _ := txNumsReader.First(applyTx)
+ return 0, 0, 0, fmt.Errorf("seems broken TxNums index not filled. can't find blockNum of txNum=%d; in db: (%d-%d, %d-%d)", inputTxNum, _fb, _lb, _ft, _lt)
+ }
+ {
+ _max, _ := txNumsReader.Max(applyTx, _blockNum)
+ if doms.TxNum() == _max {
+ _blockNum++
+ }
+ }
+
+ _min, err := txNumsReader.Min(applyTx, _blockNum)
+ if err != nil {
+ return 0, 0, 0, err
+ }
+
+ if doms.TxNum() > _min {
+ // if stopped in the middle of the block: start from beginning of block.
+ // first part will be executed in HistoryExecution mode
+ offsetFromBlockBeginning = doms.TxNum() - _min
+ }
+
+ inputTxNum = _min
+
+ //_max, _ := txNumsReader.Max(applyTx, blockNum)
+ //fmt.Printf("[commitment] found domain.txn %d, inputTxn %d, offset %d. DB found block %d {%d, %d}\n", doms.TxNum(), inputTxNum, offsetFromBlockBeginning, blockNum, _min, _max)
+ doms.SetBlockNum(_blockNum)
+ doms.SetTxNum(inputTxNum)
+ return inputTxNum, maxTxNum, offsetFromBlockBeginning, nil
+}
+
+func nothingToExec(applyTx kv.Tx, txNumsReader rawdbv3.TxNumsReader, inputTxNum uint64) (bool, error) {
+ _, lastTxNum, err := txNumsReader.Last(applyTx)
+ if err != nil {
+ return false, err
+ }
+ return lastTxNum == inputTxNum, nil
+}
+
func ExecV3(ctx context.Context,
execStage *StageState, u Unwinder, workerCount int, cfg ExecuteBlockCfg, txc wrap.TxContainer,
parallel bool, //nolint
@@ -198,100 +263,17 @@ func ExecV3(ctx context.Context,
}
txNumInDB := doms.TxNum()
- txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, cfg.blockReader))
-
var (
- inputTxNum = doms.TxNum()
- stageProgress = execStage.BlockNumber
- outputTxNum = atomic.Uint64{}
- blockComplete = atomic.Bool{}
-
+ inputTxNum = doms.TxNum()
+ stageProgress = execStage.BlockNumber
+ outputTxNum = atomic.Uint64{}
+ blockComplete = atomic.Bool{}
+ outputBlockNum = stages.SyncMetrics[stages.Execution]
+ inputBlockNum = &atomic.Uint64{}
offsetFromBlockBeginning uint64
blockNum, maxTxNum uint64
)
- blockComplete.Store(true)
- nothingToExec := func(applyTx kv.Tx) (bool, error) {
- _, lastTxNum, err := txNumsReader.Last(applyTx)
- if err != nil {
- return false, err
- }
- return lastTxNum == inputTxNum, nil
- }
- // Cases:
- // 1. Snapshots > ExecutionStage: snapshots can have half-block data `10.4`. Get right txNum from SharedDomains (after SeekCommitment)
- // 2. ExecutionStage > Snapshots: no half-block data possible. Rely on DB.
- restoreTxNum := func(applyTx kv.Tx) error {
- var err error
- maxTxNum, err = txNumsReader.Max(applyTx, maxBlockNum)
- if err != nil {
- return err
- }
- ok, _blockNum, err := txNumsReader.FindBlockNum(applyTx, doms.TxNum())
- if err != nil {
- return err
- }
- if !ok {
- _lb, _lt, _ := txNumsReader.Last(applyTx)
- _fb, _ft, _ := txNumsReader.First(applyTx)
- return fmt.Errorf("seems broken TxNums index not filled. can't find blockNum of txNum=%d; in db: (%d-%d, %d-%d)", inputTxNum, _fb, _lb, _ft, _lt)
- }
- {
- _max, _ := txNumsReader.Max(applyTx, _blockNum)
- if doms.TxNum() == _max {
- _blockNum++
- }
- }
-
- _min, err := txNumsReader.Min(applyTx, _blockNum)
- if err != nil {
- return err
- }
-
- if doms.TxNum() > _min {
- // if stopped in the middle of the block: start from beginning of block.
- // first part will be executed in HistoryExecution mode
- offsetFromBlockBeginning = doms.TxNum() - _min
- }
-
- inputTxNum = _min
- outputTxNum.Store(inputTxNum)
-
- //_max, _ := txNumsReader.Max(applyTx, blockNum)
- //fmt.Printf("[commitment] found domain.txn %d, inputTxn %d, offset %d. DB found block %d {%d, %d}\n", doms.TxNum(), inputTxNum, offsetFromBlockBeginning, blockNum, _min, _max)
- doms.SetBlockNum(_blockNum)
- doms.SetTxNum(inputTxNum)
- return nil
- }
- if applyTx != nil {
- if _nothing, err := nothingToExec(applyTx); err != nil {
- return err
- } else if _nothing {
- return nil
- }
-
- if err := restoreTxNum(applyTx); err != nil {
- return err
- }
- } else {
- var _nothing bool
- if err := cfg.db.View(ctx, func(tx kv.Tx) (err error) {
- if _nothing, err = nothingToExec(applyTx); err != nil {
- return err
- } else if _nothing {
- return nil
- }
-
- return restoreTxNum(applyTx)
- }); err != nil {
- return err
- }
- if _nothing {
- return nil
- }
- }
-
- ts := time.Duration(0)
blockNum = doms.BlockNum()
outputTxNum.Store(doms.TxNum())
@@ -311,8 +293,6 @@ func ExecV3(ctx context.Context,
agg.BuildFilesInBackground(outputTxNum.Load())
- var outputBlockNum = stages.SyncMetrics[stages.Execution]
- inputBlockNum := &atomic.Uint64{}
var count uint64
shouldReportToTxPool := cfg.notifications != nil && !isMining && maxBlockNum <= blockNum+64
@@ -329,22 +309,37 @@ func ExecV3(ctx context.Context,
// Now rwLoop closing both (because applyLoop we completely restart)
// Maybe need split channels? Maybe don't exit from ApplyLoop? Maybe current way is also ok?
- // input queue
- in := state.NewQueueWithRetry(100_000)
- defer in.Close()
+ if applyTx != nil {
+ if inputTxNum, maxTxNum, offsetFromBlockBeginning, err = restoreTxNum(ctx, &cfg, applyTx, doms, maxBlockNum); err != nil {
+ return err
+ }
+ } else {
+ if err := cfg.db.View(ctx, func(tx kv.Tx) (err error) {
+ inputTxNum, maxTxNum, offsetFromBlockBeginning, err = restoreTxNum(ctx, &cfg, tx, doms, maxBlockNum)
+ return err
+ }); err != nil {
+ return err
+ }
+ }
- rwsConsumed := make(chan struct{}, 1)
- defer close(rwsConsumed)
+ if maxTxNum == 0 {
+ return nil
+ }
applyWorker := cfg.applyWorker
if isMining {
applyWorker = cfg.applyWorkerMining
}
- applyWorker.ResetState(rs, accumulator)
defer applyWorker.LogLRUStats()
+ applyWorker.ResetState(rs, accumulator)
+
commitThreshold := cfg.batchSize.Bytes()
+
+ // TODO are these dups ?
+ processed := NewProgress(blockNum, commitThreshold, workerCount, true, execStage.LogPrefix(), logger)
progress := NewProgress(blockNum, commitThreshold, workerCount, false, execStage.LogPrefix(), logger)
+
logEvery := time.NewTicker(20 * time.Second)
defer logEvery.Stop()
pruneEvery := time.NewTicker(2 * time.Second)
@@ -352,27 +347,27 @@ func ExecV3(ctx context.Context,
var logGas uint64
var stepsInDB float64
-
- processed := NewProgress(blockNum, commitThreshold, workerCount, true, execStage.LogPrefix(), logger)
-
var executor executor
if parallel {
pe := ¶llelExecutor{
- execStage: execStage,
- chainDb: cfg.db,
- applyWorker: applyWorker,
- applyTx: applyTx,
- outputTxNum: &outputTxNum,
- in: in,
- rs: rs,
- agg: agg,
- rwsConsumed: rwsConsumed,
- isMining: isMining,
- inMemExec: inMemExec,
+ txExecutor: txExecutor{
+ cfg: cfg,
+ execStage: execStage,
+ rs: rs,
+ doms: doms,
+ agg: agg,
+ accumulator: accumulator,
+ isMining: isMining,
+ inMemExec: inMemExec,
+ applyTx: applyTx,
+ applyWorker: applyWorker,
+ outputTxNum: &outputTxNum,
+ outputBlockNum: stages.SyncMetrics[stages.Execution],
+ logger: logger,
+ },
shouldGenerateChangesets: shouldGenerateChangesets,
workerCount: workerCount,
- accumulator: accumulator,
pruneEvery: pruneEvery,
logEvery: logEvery,
progress: progress,
@@ -382,7 +377,7 @@ func ExecV3(ctx context.Context,
defer executorCancel()
defer func() {
- processed.Log("Done", executor.readState(), in, pe.rws, 0 /*txCount - TODO*/, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec)
+ processed.Log("Done", executor.readState(), nil, pe.rws, 0 /*txCount - TODO*/, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec)
}()
executor = pe
@@ -391,31 +386,47 @@ func ExecV3(ctx context.Context,
doms.SetTx(applyTx)
se := &serialExecutor{
- cfg: cfg,
- execStage: execStage,
- rs: rs,
- doms: doms,
- agg: agg,
- u: u,
- isMining: isMining,
- inMemExec: inMemExec,
- applyTx: applyTx,
- worker: applyWorker,
- outputTxNum: &outputTxNum,
- logger: logger,
+ txExecutor: txExecutor{
+ cfg: cfg,
+ execStage: execStage,
+ rs: rs,
+ doms: doms,
+ agg: agg,
+ u: u,
+ isMining: isMining,
+ inMemExec: inMemExec,
+ applyTx: applyTx,
+ applyWorker: applyWorker,
+ outputTxNum: &outputTxNum,
+ outputBlockNum: stages.SyncMetrics[stages.Execution],
+ logger: logger,
+ },
}
defer func() {
- processed.Log("Done", executor.readState(), in, nil, se.txCount, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec)
+ processed.Log("Done", executor.readState(), nil, nil, se.txCount, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec)
}()
executor = se
}
- getHeaderFunc := func(hash common.Hash, number uint64) (h *types.Header) {
- return executor.getHeader(ctx, hash, number)
+ blockComplete.Store(true)
+
+ ts := time.Duration(0)
+ blockNum = executor.domains().BlockNum()
+ outputTxNum.Store(executor.domains().TxNum())
+
+ if maxBlockNum < blockNum {
+ return nil
}
+ if maxBlockNum > blockNum+16 {
+ log.Info(fmt.Sprintf("[%s] starting", execStage.LogPrefix()),
+ "from", blockNum, "to", maxBlockNum, "fromTxNum", executor.domains().TxNum(), "offsetFromBlockBeginning", offsetFromBlockBeginning, "initialCycle", initialCycle, "useExternalTx", useExternalTx)
+ }
+
+ agg.BuildFilesInBackground(outputTxNum.Load())
+
var readAhead chan uint64
if !parallel {
// snapshots are often stored on chaper drives. don't expect low-read-latency and manually read-ahead.
@@ -478,13 +489,12 @@ Loop:
skipAnalysis := core.SkipAnalysis(chainConfig, blockNum)
signer := *types.MakeSigner(chainConfig, blockNum, header.Time)
- f := core.GetHashFn(header, getHeaderFunc)
getHashFnMute := &sync.Mutex{}
- getHashFn := func(n uint64) common.Hash {
+ getHashFn := core.GetHashFn(header, func(hash common.Hash, number uint64) (h *types.Header) {
getHashFnMute.Lock()
defer getHashFnMute.Unlock()
- return f(n)
- }
+ return executor.getHeader(ctx, hash, number)
+ })
totalGasUsed += b.GasUsed()
blockContext := core.NewEVMBlockContext(header, getHashFn, cfg.engine, cfg.author /* author */, chainConfig)
// print type of engine
@@ -492,7 +502,7 @@ Loop:
if err := executor.status(ctx, commitThreshold); err != nil {
return err
}
- } else if shouldReportToTxPool {
+ } else if accumulator != nil {
txs, err := blockReader.RawTransactions(context.Background(), executor.tx(), b.NumberU64(), b.NumberU64())
if err != nil {
return err
@@ -610,9 +620,16 @@ Loop:
aggTx := executor.tx().(state2.HasAggTx).AggTx().(*state2.AggregatorRoTx)
aggTx.RestrictSubsetFileDeletions(true)
start := time.Now()
- if _, err := executor.domains().ComputeCommitment(ctx, true, blockNum, execStage.LogPrefix()); err != nil {
+ _ /*rh*/, err := executor.domains().ComputeCommitment(ctx, true, blockNum, execStage.LogPrefix())
+ if err != nil {
return err
}
+
+ //if !bytes.Equal(rh, header.Root.Bytes()) {
+ // logger.Error(fmt.Sprintf("[%s] Wrong trie root of block %d: %x, expected (from header): %x. Block hash: %x", execStage.LogPrefix(), header.Number.Uint64(), rh, header.Root.Bytes(), header.Hash()))
+ // return errors.New("wrong trie root")
+ //}
+
ts += time.Since(start)
aggTx.RestrictSubsetFileDeletions(false)
executor.domains().SavePastChangesetAccumulator(b.Hash(), blockNum, changeset)
@@ -637,8 +654,6 @@ Loop:
metrics2.UpdateBlockConsumerPostExecutionDelay(b.Time(), blockNum, logger)
}
- outputBlockNum.SetUint64(blockNum)
-
select {
case <-logEvery.C:
if inMemExec || isMining {
@@ -646,7 +661,7 @@ Loop:
}
stepsInDB := rawdbhelpers.IdxStepsCountV3(executor.tx())
- progress.Log("", executor.readState(), in, nil, count, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec)
+ progress.Log("", executor.readState(), nil, nil, count, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec)
//TODO: https://github.com/erigontech/erigon/issues/10724
//if executor.tx().(state2.HasAggTx).AggTx().(*state2.AggregatorRoTx).CanPrune(executor.tx(), outputTxNum.Load()) {
@@ -712,6 +727,7 @@ Loop:
//log.Info("Executed", "blocks", inputBlockNum.Load(), "txs", outputTxNum.Load(), "repeats", mxExecRepeats.GetValueUint64())
+ //fmt.Println("WAIT")
executor.wait()
if u != nil && !u.HasUnwindPoint() {
diff --git a/eth/stagedsync/exec3_parallel.go b/eth/stagedsync/exec3_parallel.go
index 4ca19d50142..26d06c369f5 100644
--- a/eth/stagedsync/exec3_parallel.go
+++ b/eth/stagedsync/exec3_parallel.go
@@ -13,14 +13,16 @@ import (
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon-lib/log/v3"
+ "github.com/erigontech/erigon-lib/metrics"
state2 "github.com/erigontech/erigon-lib/state"
"github.com/erigontech/erigon/cmd/state/exec3"
"github.com/erigontech/erigon/consensus"
+ "github.com/erigontech/erigon/core"
"github.com/erigontech/erigon/core/rawdb"
"github.com/erigontech/erigon/core/rawdb/rawdbhelpers"
"github.com/erigontech/erigon/core/state"
"github.com/erigontech/erigon/core/types"
- "github.com/erigontech/erigon/eth/stagedsync/stages"
+ "github.com/erigontech/erigon/core/vm"
"github.com/erigontech/erigon/turbo/shards"
"golang.org/x/sync/errgroup"
)
@@ -78,54 +80,48 @@ type executor interface {
domains() *state2.SharedDomains
}
-type parallelExecutor struct {
+type txExecutor struct {
sync.RWMutex
- rwLoopErrCh chan error
- rwLoopG *errgroup.Group
- applyLoopWg sync.WaitGroup
- chainDb kv.RwDB
- applyTx kv.RwTx
- applyWorker *exec3.Worker
- execWorkers []*exec3.Worker
- stopWorkers func()
- waitWorkers func()
- execStage *StageState
- cfg ExecuteBlockCfg
- lastBlockNum atomic.Uint64
- outputTxNum *atomic.Uint64
- in *state.QueueWithRetry
- rws *state.ResultsQueue
- rs *state.StateV3
- doms *state2.SharedDomains
- agg *state2.Aggregator
- rwsConsumed chan struct{}
- isMining bool
- inMemExec bool
- shouldGenerateChangesets bool
- accumulator *shards.Accumulator
- workerCount int
- pruneEvery *time.Ticker
- logEvery *time.Ticker
- slowDownLimit *time.Ticker
- progress *Progress
+ cfg ExecuteBlockCfg
+ execStage *StageState
+ agg *state2.Aggregator
+ rs *state.StateV3
+ doms *state2.SharedDomains
+ accumulator *shards.Accumulator
+ u Unwinder
+ isMining bool
+ inMemExec bool
+ applyTx kv.RwTx
+ applyWorker *exec3.Worker
+ outputTxNum *atomic.Uint64
+ outputBlockNum metrics.Gauge
+ logger log.Logger
}
-func (pe *parallelExecutor) tx() kv.RwTx {
- return pe.applyTx
+func (te *txExecutor) tx() kv.RwTx {
+ return te.applyTx
}
-func (pe *parallelExecutor) readState() *state.StateV3 {
- return pe.rs
+func (te *txExecutor) readState() *state.StateV3 {
+ return te.rs
}
-func (pe *parallelExecutor) domains() *state2.SharedDomains {
- return pe.doms
+func (te *txExecutor) domains() *state2.SharedDomains {
+ return te.doms
}
-func (pe *parallelExecutor) getHeader(ctx context.Context, hash common.Hash, number uint64) (h *types.Header) {
+func (te *txExecutor) getHeader(ctx context.Context, hash common.Hash, number uint64) (h *types.Header) {
var err error
- if err = pe.chainDb.View(ctx, func(tx kv.Tx) error {
- h, err = pe.cfg.blockReader.Header(ctx, tx, hash, number)
+ if te.applyTx != nil {
+ h, err = te.cfg.blockReader.Header(ctx, te.applyTx, hash, number)
+ if err != nil {
+ panic(err)
+ }
+ return h
+ }
+
+ if err = te.cfg.db.View(ctx, func(tx kv.Tx) error {
+ h, err = te.cfg.blockReader.Header(ctx, tx, hash, number)
if err != nil {
return err
}
@@ -136,19 +132,39 @@ func (pe *parallelExecutor) getHeader(ctx context.Context, hash common.Hash, num
return h
}
+type parallelExecutor struct {
+ txExecutor
+ rwLoopErrCh chan error
+ rwLoopG *errgroup.Group
+ applyLoopWg sync.WaitGroup
+ execWorkers []*exec3.Worker
+ stopWorkers func()
+ waitWorkers func()
+ lastBlockNum atomic.Uint64
+ in *state.QueueWithRetry
+ rws *state.ResultsQueue
+ rwsConsumed chan struct{}
+ shouldGenerateChangesets bool
+ workerCount int
+ pruneEvery *time.Ticker
+ logEvery *time.Ticker
+ slowDownLimit *time.Ticker
+ progress *Progress
+}
+
func (pe *parallelExecutor) applyLoop(ctx context.Context, maxTxNum uint64, blockComplete *atomic.Bool, errCh chan error) {
defer pe.applyLoopWg.Done()
defer func() {
if rec := recover(); rec != nil {
- log.Warn("[dbg] apply loop panic", "rec", rec)
+ pe.logger.Warn("[dbg] apply loop panic", "rec", rec)
}
- log.Warn("[dbg] apply loop exit")
+ pe.logger.Warn("[dbg] apply loop exit")
}()
-
- outputBlockNum := stages.SyncMetrics[stages.Execution]
+ //fmt.Println("applyLoop started")
+ //defer fmt.Println("applyLoop done")
applyLoopInner := func(ctx context.Context) error {
- tx, err := pe.chainDb.BeginRo(ctx)
+ tx, err := pe.cfg.db.BeginRo(ctx)
if err != nil {
return err
}
@@ -161,18 +177,15 @@ func (pe *parallelExecutor) applyLoop(ctx context.Context, maxTxNum uint64, bloc
return err
}
- processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err :=
- pe.processResultQueue(ctx, pe.outputTxNum.Load(), tx, pe.rwsConsumed, true, false)
+ processedTxNum, conflicts, triggers, _ /*processedBlockNum*/, stoppedAtBlockEnd, err :=
+ pe.processResultQueue(ctx, pe.outputTxNum.Load(), pe.rwsConsumed, true, false)
if err != nil {
return err
}
-
+ //fmt.Println("QR", processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err)
mxExecRepeats.AddInt(conflicts)
mxExecTriggers.AddInt(triggers)
- if processedBlockNum > pe.lastBlockNum.Load() {
- outputBlockNum.SetUint64(processedBlockNum)
- pe.lastBlockNum.Store(processedBlockNum)
- }
+
if processedTxNum > 0 {
pe.outputTxNum.Store(processedTxNum)
blockComplete.Store(stoppedAtBlockEnd)
@@ -195,11 +208,17 @@ func (pe *parallelExecutor) applyLoop(ctx context.Context, maxTxNum uint64, bloc
// Maybe need split channels? Maybe don't exit from ApplyLoop? Maybe current way is also ok?
func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger log.Logger) error {
- tx, err := pe.chainDb.BeginRw(ctx)
- if err != nil {
- return err
+ //fmt.Println("rwLoop started", maxTxNum)
+ //defer fmt.Println("rwLoop done")
+
+ tx := pe.applyTx
+ if tx == nil {
+ tx, err := pe.cfg.db.BeginRw(ctx)
+ if err != nil {
+ return err
+ }
+ defer tx.Rollback()
}
- defer tx.Rollback()
pe.doms.SetTx(tx)
@@ -213,8 +232,6 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger
go pe.applyLoop(applyCtx, maxTxNum, &blockComplete, pe.rwLoopErrCh)
- outputBlockNum := stages.SyncMetrics[stages.Execution]
-
for pe.outputTxNum.Load() <= maxTxNum {
select {
case <-ctx.Done():
@@ -222,16 +239,16 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger
case <-pe.logEvery.C:
stepsInDB := rawdbhelpers.IdxStepsCountV3(tx)
- pe.progress.Log("", pe.rs, pe.in, pe.rws, pe.rs.DoneCount(), 0 /* TODO logGas*/, pe.lastBlockNum.Load(), outputBlockNum.GetValueUint64(), pe.outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, pe.shouldGenerateChangesets, pe.inMemExec)
+ pe.progress.Log("", pe.rs, pe.in, pe.rws, pe.rs.DoneCount(), 0 /* TODO logGas*/, pe.lastBlockNum.Load(), pe.outputBlockNum.GetValueUint64(), pe.outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, pe.shouldGenerateChangesets, pe.inMemExec)
if pe.agg.HasBackgroundFilesBuild() {
logger.Info(fmt.Sprintf("[%s] Background files build", pe.execStage.LogPrefix()), "progress", pe.agg.BackgroundProgress())
}
case <-pe.pruneEvery.C:
if pe.rs.SizeEstimate() < pe.cfg.batchSize.Bytes() {
- if pe.doms.BlockNum() != outputBlockNum.GetValueUint64() {
- panic(fmt.Errorf("%d != %d", pe.doms.BlockNum(), outputBlockNum.GetValueUint64()))
+ if pe.doms.BlockNum() != pe.outputBlockNum.GetValueUint64() {
+ panic(fmt.Errorf("%d != %d", pe.doms.BlockNum(), pe.outputBlockNum.GetValueUint64()))
}
- _, err := pe.doms.ComputeCommitment(ctx, true, outputBlockNum.GetValueUint64(), pe.execStage.LogPrefix())
+ _, err := pe.doms.ComputeCommitment(ctx, true, pe.outputBlockNum.GetValueUint64(), pe.execStage.LogPrefix())
if err != nil {
return err
}
@@ -264,7 +281,7 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger
pe.applyWorker.ResetTx(tx)
processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err :=
- pe.processResultQueue(ctx, pe.outputTxNum.Load(), tx, nil, false, true)
+ pe.processResultQueue(ctx, pe.outputTxNum.Load(), nil, false, true)
if err != nil {
return err
}
@@ -272,7 +289,7 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger
mxExecRepeats.AddInt(conflicts)
mxExecTriggers.AddInt(triggers)
if processedBlockNum > 0 {
- outputBlockNum.SetUint64(processedBlockNum)
+ pe.outputBlockNum.SetUint64(processedBlockNum)
}
if processedTxNum > 0 {
pe.outputTxNum.Store(processedTxNum)
@@ -309,16 +326,16 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger
pe.doms.ClearRam(true)
t3 = time.Since(tt)
- if err = pe.execStage.Update(tx, outputBlockNum.GetValueUint64()); err != nil {
+ if err := pe.execStage.Update(tx, pe.outputBlockNum.GetValueUint64()); err != nil {
return err
}
- if _, err = rawdb.IncrementStateVersion(pe.applyTx); err != nil {
+ if _, err := rawdb.IncrementStateVersion(tx); err != nil {
return fmt.Errorf("writing plain state version: %w", err)
}
tx.CollectMetrics()
tt = time.Now()
- if err = tx.Commit(); err != nil {
+ if err := tx.Commit(); err != nil {
return err
}
t4 = time.Since(tt)
@@ -330,7 +347,8 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger
}(); err != nil {
return err
}
- if tx, err = pe.chainDb.BeginRw(ctx); err != nil {
+ var err error
+ if tx, err = pe.cfg.db.BeginRw(ctx); err != nil {
return err
}
defer tx.Rollback()
@@ -344,29 +362,35 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger
logger.Info("Committed", "time", time.Since(commitStart), "drain", t0, "drain_and_lock", t1, "rs.flush", t2, "agg.flush", t3, "tx.commit", t4)
}
}
- if err = pe.doms.Flush(ctx, tx); err != nil {
+ if err := pe.doms.Flush(ctx, tx); err != nil {
return err
}
- if err = pe.execStage.Update(tx, outputBlockNum.GetValueUint64()); err != nil {
+ if err := pe.execStage.Update(tx, pe.outputBlockNum.GetValueUint64()); err != nil {
return err
}
- if err = tx.Commit(); err != nil {
+ if err := tx.Commit(); err != nil {
return err
}
return nil
}
-func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum uint64, applyTx kv.Tx, backPressure chan<- struct{}, canRetry, forceStopAtBlockEnd bool) (outputTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) {
+func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum uint64, backPressure chan<- struct{}, canRetry, forceStopAtBlockEnd bool) (outputTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) {
rwsIt := pe.rws.Iter()
defer rwsIt.Close()
+ //defer fmt.Println("PRQ", "Done")
var i int
outputTxNum = inputTxNum
for rwsIt.HasNext(outputTxNum) {
txTask := rwsIt.PopNext()
+ //fmt.Println("PRQ", txTask.BlockNum, txTask.TxIndex, txTask.TxNum)
if txTask.Error != nil || !pe.rs.ReadsValid(txTask.ReadLists) {
conflicts++
-
+ //fmt.Println(txTask.TxNum, txTask.Error)
+ if errors.Is(txTask.Error, vm.ErrIntraBlockStateFailed) ||
+ errors.Is(txTask.Error, core.ErrStateTransitionFailed) {
+ return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("%w: %v", consensus.ErrInvalidBlock, txTask.Error)
+ }
if i > 0 && canRetry {
//send to re-exex
pe.rs.ReTry(txTask, pe.in)
@@ -374,8 +398,9 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u
}
// resolve first conflict right here: it's faster and conflict-free
- pe.applyWorker.RunTxTask(txTask, pe.isMining)
+ pe.applyWorker.RunTxTaskNoLock(txTask.Reset(), pe.isMining)
if txTask.Error != nil {
+ //fmt.Println("RETRY", txTask.TxNum, txTask.Error)
return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("%w: %v", consensus.ErrInvalidBlock, txTask.Error)
}
if pe.cfg.syncCfg.ChaosMonkey {
@@ -395,6 +420,11 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u
if err != nil {
return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err)
}
+
+ if processedBlockNum > pe.lastBlockNum.Load() {
+ pe.outputBlockNum.SetUint64(processedBlockNum)
+ pe.lastBlockNum.Store(processedBlockNum)
+ }
//if !bytes.Equal(rh, txTask.BlockRoot[:]) {
// log.Error("block hash mismatch", "rh", hex.EncodeToString(rh), "blockRoot", hex.EncodeToString(txTask.BlockRoot[:]), "bn", txTask.BlockNum, "txn", txTask.TxNum)
// return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("block hashk mismatch: %x != %x bn =%d, txn= %d", rh, txTask.BlockRoot[:], txTask.BlockNum, txTask.TxNum)
@@ -412,7 +442,9 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u
return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err)
}
processedBlockNum = txTask.BlockNum
- stopedAtBlockEnd = txTask.Final
+ if !stopedAtBlockEnd {
+ stopedAtBlockEnd = txTask.Final
+ }
if forceStopAtBlockEnd && txTask.Final {
break
}
@@ -422,8 +454,12 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u
func (pe *parallelExecutor) run(ctx context.Context, maxTxNum uint64, logger log.Logger) context.CancelFunc {
pe.slowDownLimit = time.NewTicker(time.Second)
+ pe.rwsConsumed = make(chan struct{}, 1)
+ pe.rwLoopErrCh = make(chan error)
+ pe.in = state.NewQueueWithRetry(100_000)
+
pe.execWorkers, _, pe.rws, pe.stopWorkers, pe.waitWorkers = exec3.NewWorkersPool(
- pe.RWMutex.RLocker(), pe.accumulator, logger, ctx, true, pe.chainDb, pe.rs, pe.in,
+ pe.RWMutex.RLocker(), pe.accumulator, logger, ctx, true, pe.cfg.db, pe.rs, pe.in,
pe.cfg.blockReader, pe.cfg.chainConfig, pe.cfg.genesis, pe.cfg.engine, pe.workerCount+1, pe.cfg.dirs, pe.isMining)
rwLoopCtx, rwLoopCtxCancel := context.WithCancel(ctx)
@@ -433,7 +469,7 @@ func (pe *parallelExecutor) run(ctx context.Context, maxTxNum uint64, logger log
defer pe.in.Close()
defer pe.applyLoopWg.Wait()
defer func() {
- log.Warn("[dbg] rwloop exit")
+ logger.Warn("[dbg] rwloop exit")
}()
return pe.rwLoop(rwLoopCtx, maxTxNum, logger)
})
@@ -443,6 +479,8 @@ func (pe *parallelExecutor) run(ctx context.Context, maxTxNum uint64, logger log
pe.slowDownLimit.Stop()
pe.wait()
pe.stopWorkers()
+ close(pe.rwsConsumed)
+ pe.in.Close()
}
}
diff --git a/eth/stagedsync/exec3_serial.go b/eth/stagedsync/exec3_serial.go
index 2a59dc12099..cb271284533 100644
--- a/eth/stagedsync/exec3_serial.go
+++ b/eth/stagedsync/exec3_serial.go
@@ -4,40 +4,22 @@ import (
"context"
"errors"
"fmt"
- "sync/atomic"
"time"
chaos_monkey "github.com/erigontech/erigon/tests/chaos-monkey"
- "github.com/erigontech/erigon-lib/common"
- "github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon-lib/log/v3"
state2 "github.com/erigontech/erigon-lib/state"
- "github.com/erigontech/erigon/cmd/state/exec3"
"github.com/erigontech/erigon/consensus"
"github.com/erigontech/erigon/core"
"github.com/erigontech/erigon/core/rawdb/rawtemporaldb"
"github.com/erigontech/erigon/core/state"
"github.com/erigontech/erigon/core/types"
- "github.com/erigontech/erigon/turbo/shards"
)
type serialExecutor struct {
- cfg ExecuteBlockCfg
- execStage *StageState
- agg *state2.Aggregator
- rs *state.StateV3
- doms *state2.SharedDomains
- accumulator *shards.Accumulator
- u Unwinder
- isMining bool
- inMemExec bool
+ txExecutor
skipPostEvaluation bool
- applyTx kv.RwTx
- worker *exec3.Worker
- outputTxNum *atomic.Uint64
- logger log.Logger
-
// outputs
txCount uint64
usedGas uint64
@@ -58,7 +40,7 @@ func (se *serialExecutor) execute(ctx context.Context, tasks []*state.TxTask) (c
return false, nil
}
- se.worker.RunTxTaskNoLock(txTask, se.isMining)
+ se.applyWorker.RunTxTaskNoLock(txTask, se.isMining)
if err := func() error {
if errors.Is(txTask.Error, context.Canceled) {
return txTask.Error
@@ -91,6 +73,8 @@ func (se *serialExecutor) execute(ctx context.Context, tasks []*state.TxTask) (c
return fmt.Errorf("%w, txnIdx=%d, %v", consensus.ErrInvalidBlock, txTask.TxIndex, err) //same as in stage_exec.go
}
}
+
+ se.outputBlockNum.SetUint64(txTask.BlockNum)
}
if se.cfg.syncCfg.ChaosMonkey {
chaosErr := chaos_monkey.ThrowRandomConsensusError(se.execStage.CurrentSyncCycle.IsInitialCycle, txTask.TxIndex, se.cfg.badBlockHalt, txTask.Error)
@@ -149,27 +133,6 @@ func (se *serialExecutor) execute(ctx context.Context, tasks []*state.TxTask) (c
return true, nil
}
-func (se *serialExecutor) tx() kv.RwTx {
- return se.applyTx
-}
-
-func (se *serialExecutor) readState() *state.StateV3 {
- return se.rs
-}
-
-func (se *serialExecutor) domains() *state2.SharedDomains {
- return se.doms
-}
-
-func (se *serialExecutor) getHeader(ctx context.Context, hash common.Hash, number uint64) (h *types.Header) {
- var err error
- h, err = se.cfg.blockReader.Header(ctx, se.applyTx, hash, number)
- if err != nil {
- panic(err)
- }
- return h
-}
-
func (se *serialExecutor) commit(ctx context.Context, txNum uint64, blockNum uint64, useExternalTx bool) (t2 time.Duration, err error) {
se.doms.Close()
if err = se.execStage.Update(se.applyTx, blockNum); err != nil {
@@ -199,8 +162,8 @@ func (se *serialExecutor) commit(ctx context.Context, txNum uint64, blockNum uin
se.doms.SetTxNum(txNum)
se.rs = state.NewStateV3(se.doms, se.logger)
- se.worker.ResetTx(se.applyTx)
- se.worker.ResetState(se.rs, se.accumulator)
+ se.applyWorker.ResetTx(se.applyTx)
+ se.applyWorker.ResetState(se.rs, se.accumulator)
return t2, nil
}
diff --git a/eth/stagedsync/stage_txlookup.go b/eth/stagedsync/stage_txlookup.go
index 42884727d78..8083945b318 100644
--- a/eth/stagedsync/stage_txlookup.go
+++ b/eth/stagedsync/stage_txlookup.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/erigontech/erigon-lib/kv/rawdbv3"
+
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/eth/stagedsync/stages"
@@ -136,7 +137,7 @@ func SpawnTxLookup(s *StageState, tx kv.RwTx, toBlock uint64, cfg TxLookupCfg, c
// txnLookupTransform - [startKey, endKey)
func txnLookupTransform(logPrefix string, tx kv.RwTx, blockFrom, blockTo uint64, ctx context.Context, cfg TxLookupCfg, logger log.Logger) (err error) {
- bigNum := new(big.Int)
+ data := make([]byte, 16)
return etl.Transform(logPrefix, tx, kv.HeaderCanonical, kv.TxLookup, cfg.tmpdir, func(k, v []byte, next etl.ExtractNextFunc) error {
blocknum, blockHash := binary.BigEndian.Uint64(k), libcommon.CastToHash(v)
body, err := cfg.blockReader.BodyWithTransactions(ctx, tx, blockHash, blocknum)
@@ -148,9 +149,21 @@ func txnLookupTransform(logPrefix string, tx kv.RwTx, blockFrom, blockTo uint64,
return nil
}
- blockNumBytes := bigNum.SetUint64(blocknum).Bytes()
- for _, txn := range body.Transactions {
- if err := next(k, txn.Hash().Bytes(), blockNumBytes); err != nil {
+ firstTxNumInBlock, err := rawdbv3.TxNums.Min(tx, blocknum)
+ if err != nil {
+ return err
+ }
+
+ if firstTxNumInBlock == 0 {
+ log.Warn(fmt.Sprintf("[%s] transform: empty txnum %d, hash %x", logPrefix, firstTxNumInBlock, v))
+ return nil
+ }
+
+ binary.BigEndian.PutUint64(data[:8], blocknum)
+
+ for i, txn := range body.Transactions {
+ binary.BigEndian.PutUint64(data[8:], firstTxNumInBlock+uint64(i)+1)
+ if err := next(k, txn.Hash().Bytes(), data); err != nil {
return err
}
}
@@ -294,6 +307,7 @@ func PruneTxLookup(s *PruneState, tx kv.RwTx, cfg TxLookupCfg, ctx context.Conte
if err != nil {
return fmt.Errorf("prune TxLookUp: %w", err)
}
+
if cfg.borConfig != nil && pruneBor {
if err = deleteBorTxLookupRange(tx, logPrefix, pruneBlockNum, pruneBlockNum+1, ctx, cfg, logger); err != nil {
return fmt.Errorf("prune BorTxLookUp: %w", err)
diff --git a/eth/stagedsync/stage_witness.go b/eth/stagedsync/stage_witness.go
new file mode 100644
index 00000000000..d1143980eed
--- /dev/null
+++ b/eth/stagedsync/stage_witness.go
@@ -0,0 +1,146 @@
+package stagedsync
+
+import (
+ "bytes"
+ "context"
+
+ "github.com/c2h5oh/datasize"
+ "github.com/erigontech/erigon-lib/chain"
+ libcommon "github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon-lib/common/datadir"
+ "github.com/erigontech/erigon-lib/kv"
+ "github.com/erigontech/erigon-lib/kv/membatchwithdb"
+ "github.com/erigontech/erigon-lib/kv/rawdbv3"
+ "github.com/erigontech/erigon-lib/log/v3"
+ "github.com/erigontech/erigon-lib/trie"
+ "github.com/erigontech/erigon-lib/wrap"
+ "github.com/erigontech/erigon/consensus"
+ "github.com/erigontech/erigon/core"
+ "github.com/erigontech/erigon/core/state"
+ "github.com/erigontech/erigon/core/types"
+ "github.com/erigontech/erigon/core/vm"
+ "github.com/erigontech/erigon/eth/ethconfig"
+ "github.com/erigontech/erigon/eth/stagedsync/stages"
+ "github.com/erigontech/erigon/ethdb/prune"
+ "github.com/erigontech/erigon/turbo/rpchelper"
+ "github.com/erigontech/erigon/turbo/services"
+)
+
+type WitnessCfg struct {
+ db kv.RwDB
+ enableWitnessGeneration bool
+ maxWitnessLimit uint64
+ chainConfig *chain.Config
+ engine consensus.Engine
+ blockReader services.FullBlockReader
+ dirs datadir.Dirs
+}
+
+type WitnessStore struct {
+ Tds *state.TrieDbState
+ TrieStateWriter *state.TrieStateWriter
+ Statedb *state.IntraBlockState
+ ChainReader *ChainReaderImpl
+ GetHashFn func(n uint64) libcommon.Hash
+}
+
+func StageWitnessCfg(enableWitnessGeneration bool, maxWitnessLimit uint64, chainConfig *chain.Config, engine consensus.Engine, blockReader services.FullBlockReader, dirs datadir.Dirs) WitnessCfg {
+ return WitnessCfg{
+ enableWitnessGeneration: enableWitnessGeneration,
+ maxWitnessLimit: maxWitnessLimit,
+ chainConfig: chainConfig,
+ engine: engine,
+ blockReader: blockReader,
+ dirs: dirs,
+ }
+}
+
+// PrepareForWitness abstracts the process of initialising bunch of necessary things required for witness
+// generation and puts them in a WitnessStore.
+func PrepareForWitness(tx kv.Tx, block *types.Block, prevRoot libcommon.Hash, cfg *WitnessCfg, ctx context.Context, logger log.Logger) (*WitnessStore, error) {
+ blockNr := block.NumberU64()
+ txNumsReader := rawdbv3.TxNums
+ reader, err := rpchelper.CreateHistoryStateReader(tx, txNumsReader, blockNr, 0, cfg.chainConfig.ChainName)
+ // stateReader, err := rpchelper.CreateHistoryStateReader(roTx, txNumsReader, blockNr, 0, "")
+ if err != nil {
+ return nil, err
+ }
+
+ tds := state.NewTrieDbState(prevRoot, blockNr-1, reader)
+ tds.SetResolveReads(true)
+
+ tds.StartNewBuffer()
+ trieStateWriter := tds.TrieStateWriter()
+
+ statedb := state.New(tds)
+
+ chainReader := NewChainReaderImpl(cfg.chainConfig, tx, cfg.blockReader, logger)
+
+ getHeader := func(hash libcommon.Hash, number uint64) *types.Header {
+ h, e := cfg.blockReader.Header(ctx, tx, hash, number)
+ if e != nil {
+ log.Error("getHeader error", "number", number, "hash", hash, "err", e)
+ }
+ return h
+ }
+ getHashFn := core.GetHashFn(block.Header(), getHeader)
+
+ return &WitnessStore{
+ Tds: tds,
+ TrieStateWriter: trieStateWriter,
+ Statedb: statedb,
+ ChainReader: chainReader,
+ GetHashFn: getHashFn,
+ }, nil
+}
+
+// RewindStagesForWitness rewinds the Execution stage to previous block.
+func RewindStagesForWitness(batch *membatchwithdb.MemoryMutation, blockNr, latestBlockNr uint64, cfg *WitnessCfg, regenerateHash bool, ctx context.Context, logger log.Logger) error {
+ // Rewind the Execution stage to previous block
+ unwindState := &UnwindState{ID: stages.Execution, UnwindPoint: blockNr - 1, CurrentBlockNumber: latestBlockNr}
+ stageState := &StageState{ID: stages.Execution, BlockNumber: blockNr}
+
+ txc := wrap.TxContainer{Tx: batch}
+ batchSizeStr := "512M"
+ var batchSize datasize.ByteSize
+ err := batchSize.UnmarshalText([]byte(batchSizeStr))
+ if err != nil {
+ return err
+ }
+
+ pruneMode := prune.Mode{
+ Initialised: false,
+ }
+ vmConfig := &vm.Config{}
+ dirs := cfg.dirs
+ blockReader := cfg.blockReader
+ syncCfg := ethconfig.Defaults.Sync
+ execCfg := StageExecuteBlocksCfg(batch.MemDB(), pruneMode, batchSize, cfg.chainConfig, cfg.engine, vmConfig, nil,
+ /*stateStream=*/ false,
+ /*badBlockHalt=*/ true, dirs, blockReader, nil, nil, syncCfg, nil)
+
+ if err := UnwindExecutionStage(unwindState, stageState, txc, ctx, execCfg, logger); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func ExecuteBlockStatelessly(block *types.Block, prevHeader *types.Header, chainReader consensus.ChainReader, tds *state.TrieDbState, cfg *WitnessCfg, buf *bytes.Buffer, getHashFn func(n uint64) libcommon.Hash, logger log.Logger) (libcommon.Hash, error) {
+ blockNr := block.NumberU64()
+ nw, err := trie.NewWitnessFromReader(bytes.NewReader(buf.Bytes()), false)
+ if err != nil {
+ return libcommon.Hash{}, err
+ }
+
+ statelessIbs, err := state.NewStateless(prevHeader.Root, nw, blockNr-1, true /* trace */, false /* is binary */)
+ if err != nil {
+ return libcommon.Hash{}, err
+ }
+ execResult, err := core.ExecuteBlockEphemerally(cfg.chainConfig, &vm.Config{}, getHashFn, cfg.engine, block, statelessIbs, statelessIbs, chainReader, nil, logger)
+ if err != nil {
+ return libcommon.Hash{}, err
+ }
+ _ = execResult
+ return statelessIbs.Finalize(), nil
+}
diff --git a/eth/stagedsync/witness_util.go b/eth/stagedsync/witness_util.go
new file mode 100644
index 00000000000..cebda023e47
--- /dev/null
+++ b/eth/stagedsync/witness_util.go
@@ -0,0 +1,247 @@
+package stagedsync
+
+import (
+ "bytes"
+ "context"
+ "encoding/binary"
+ "encoding/csv"
+ "fmt"
+ "strconv"
+
+ "github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon-lib/kv"
+ "github.com/erigontech/erigon-lib/trie"
+)
+
+type WitnessDBWriter struct {
+ storage kv.RwDB
+ statsWriter *csv.Writer
+}
+
+func NewWitnessDBWriter(storage kv.RwDB, statsWriter *csv.Writer) (*WitnessDBWriter, error) {
+ err := statsWriter.Write([]string{
+ "blockNum", "maxTrieSize", "witnessesSize",
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &WitnessDBWriter{storage, statsWriter}, nil
+}
+
+const chunkSize = 100000 // 100KB
+
+func WriteChunks(tx kv.RwTx, tableName string, key []byte, valueBytes []byte) error {
+ // Split the valueBytes into chunks and write each chunk
+ for i := 0; i < len(valueBytes); i += chunkSize {
+ end := i + chunkSize
+ if end > len(valueBytes) {
+ end = len(valueBytes)
+ }
+ chunk := valueBytes[i:end]
+ chunkKey := append(key, []byte("_chunk_"+strconv.Itoa(i/chunkSize))...)
+
+ // Write each chunk to the KV store
+ if err := tx.Put(tableName, chunkKey, chunk); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func ReadChunks(tx kv.Tx, tableName string, key []byte) ([]byte, error) {
+ // Initialize a buffer to store the concatenated chunks
+ var result []byte
+
+ // Retrieve and concatenate each chunk
+ for i := 0; ; i++ {
+ chunkKey := append(key, []byte("_chunk_"+strconv.Itoa(i))...)
+ chunk, err := tx.GetOne(tableName, chunkKey)
+ if err != nil {
+ return nil, err
+ }
+
+ // Check if this is the last chunk
+ if len(chunk) == 0 {
+ break
+ }
+
+ // Append the chunk to the result
+ result = append(result, chunk...)
+ }
+
+ return result, nil
+}
+
+// HasWitness returns whether a witness exists for the given key or not
+func HasWitness(tx kv.Tx, tableName string, key []byte) (bool, error) {
+ firstChunkKey := append(key, []byte("_chunk_0")...)
+ chunk, err := tx.GetOne(tableName, firstChunkKey)
+ if err != nil {
+ return false, err
+ }
+
+ if len(chunk) == 0 {
+ return false, nil
+ }
+
+ return true, nil
+}
+
+// DeleteChunks deletes all the chunks present with prefix `key`
+// TODO: Try to see if this can be optimised by using tx.ForEach
+// and iterate over each element with prefix `key`
+func DeleteChunks(tx kv.RwTx, tableName string, key []byte) error {
+ for i := 0; ; i++ {
+ chunkKey := append(key, []byte("_chunk_"+strconv.Itoa(i))...)
+ chunk, err := tx.GetOne(tableName, chunkKey)
+ if err != nil {
+ return err
+ }
+
+ err = tx.Delete(tableName, chunkKey)
+ if err != nil {
+ return err
+ }
+
+ // Check if this is the last chunk
+ if len(chunk) == 0 {
+ break
+ }
+ }
+
+ return nil
+}
+
+// FindOldestWitness returns the block number of the oldest stored block
+func FindOldestWitness(tx kv.Tx, tableName string) (uint64, error) {
+ cursor, err := tx.Cursor(tableName)
+ if err != nil {
+ return 0, err
+ }
+
+ k, _, err := cursor.First()
+ if err != nil {
+ return 0, err
+ }
+
+ return BytesToUint64(k), nil
+}
+
+func (db *WitnessDBWriter) MustUpsertOneWitness(blockNumber uint64, witness *trie.Witness) {
+ k := make([]byte, 8)
+
+ binary.LittleEndian.PutUint64(k, blockNumber)
+
+ var buf bytes.Buffer
+ _, err := witness.WriteInto(&buf)
+ if err != nil {
+ panic(fmt.Sprintf("error extracting witness for block %d: %v\n", blockNumber, err))
+ }
+
+ wb := buf.Bytes()
+
+ tx, err := db.storage.BeginRw(context.Background())
+ if err != nil {
+ panic(fmt.Errorf("error opening tx: %w", err))
+ }
+
+ defer tx.Rollback()
+
+ fmt.Printf("Size of witness: %d\n", len(wb))
+
+ err = WriteChunks(tx, kv.Witnesses, k, common.CopyBytes(wb))
+
+ tx.Commit()
+
+ if err != nil {
+ panic(fmt.Errorf("error while upserting witness: %w", err))
+ }
+}
+
+func (db *WitnessDBWriter) MustUpsert(blockNumber uint64, maxTrieSize uint32, resolveWitnesses []*trie.Witness) {
+ key := deriveDbKey(blockNumber, maxTrieSize)
+
+ var buf bytes.Buffer
+
+ for i, witness := range resolveWitnesses {
+ if _, err := witness.WriteInto(&buf); err != nil {
+ panic(fmt.Errorf("error while writing witness to a buffer: %w", err))
+ }
+ if i < len(resolveWitnesses)-1 {
+ buf.WriteByte(byte(trie.OpNewTrie))
+ }
+ }
+
+ bytes := buf.Bytes()
+
+ tx, err := db.storage.BeginRw(context.Background())
+ if err != nil {
+ panic(fmt.Errorf("error opening tx: %w", err))
+ }
+
+ defer tx.Rollback()
+
+ err = tx.Put(kv.Witnesses, common.CopyBytes(key), common.CopyBytes(bytes))
+
+ tx.Commit()
+
+ if err != nil {
+ panic(fmt.Errorf("error while upserting witness: %w", err))
+ }
+
+ err = db.statsWriter.Write([]string{
+ strconv.Itoa(int(blockNumber)),
+ strconv.Itoa(int(maxTrieSize)),
+ strconv.Itoa(len(bytes)),
+ })
+
+ if err != nil {
+ panic(fmt.Errorf("error while writing stats: %w", err))
+ }
+
+ db.statsWriter.Flush()
+}
+
+type WitnessDBReader struct {
+ db kv.RwDB
+}
+
+func NewWitnessDBReader(db kv.RwDB) *WitnessDBReader {
+ return &WitnessDBReader{db}
+}
+
+func (db *WitnessDBReader) GetWitnessesForBlock(blockNumber uint64, maxTrieSize uint32) ([]byte, error) {
+ key := deriveDbKey(blockNumber, maxTrieSize)
+
+ tx, err := db.db.BeginRo(context.Background())
+ if err != nil {
+ panic(fmt.Errorf("error opening tx: %w", err))
+ }
+
+ defer tx.Rollback()
+
+ return tx.GetOne(kv.Witnesses, key)
+}
+
+func deriveDbKey(blockNumber uint64, maxTrieSize uint32) []byte {
+ buffer := make([]byte, 8+4)
+
+ binary.LittleEndian.PutUint64(buffer, blockNumber)
+ binary.LittleEndian.PutUint32(buffer[8:], maxTrieSize)
+
+ return buffer
+}
+
+func BytesToUint64(b []byte) uint64 {
+ if len(b) < 8 {
+ return 0
+ }
+ return binary.BigEndian.Uint64(b)
+}
+
+func Uint64ToBytes(i uint64) []byte {
+ buf := make([]byte, 8)
+ binary.BigEndian.PutUint64(buf, i)
+ return buf
+}
diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go
index ac530454f68..7421136864e 100644
--- a/eth/tracers/js/goja.go
+++ b/eth/tracers/js/goja.go
@@ -675,8 +675,12 @@ func (do *dbObj) GetBalance(addrSlice goja.Value) goja.Value {
return nil
}
addr := libcommon.BytesToAddress(a)
- value := do.ibs.GetBalance(addr).ToBig()
- res, err := do.toBig(do.vm, value.String())
+ value, err := do.ibs.GetBalance(addr)
+ if err != nil {
+ do.vm.Interrupt(err)
+ return nil
+ }
+ res, err := do.toBig(do.vm, value.ToBig().String())
if err != nil {
do.vm.Interrupt(err)
return nil
@@ -691,7 +695,12 @@ func (do *dbObj) GetNonce(addrSlice goja.Value) uint64 {
return 0
}
addr := libcommon.BytesToAddress(a)
- return do.ibs.GetNonce(addr)
+ nonce, err := do.ibs.GetNonce(addr)
+ if err != nil {
+ do.vm.Interrupt(err)
+ return 0
+ }
+ return nonce
}
func (do *dbObj) GetCode(addrSlice goja.Value) goja.Value {
@@ -701,7 +710,11 @@ func (do *dbObj) GetCode(addrSlice goja.Value) goja.Value {
return nil
}
addr := libcommon.BytesToAddress(a)
- code := do.ibs.GetCode(addr)
+ code, err := do.ibs.GetCode(addr)
+ if err != nil {
+ do.vm.Interrupt(err)
+ return nil
+ }
res, err := do.toBuf(do.vm, code)
if err != nil {
do.vm.Interrupt(err)
@@ -740,7 +753,12 @@ func (do *dbObj) Exists(addrSlice goja.Value) bool {
return false
}
addr := libcommon.BytesToAddress(a)
- return do.ibs.Exist(addr)
+ exists, err := do.ibs.Exist(addr)
+ if err != nil {
+ do.vm.Interrupt(err)
+ return false
+ }
+ return exists
}
func (do *dbObj) setupObject() *goja.Object {
diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go
index 96624bca385..8e43dd6a44a 100644
--- a/eth/tracers/js/tracer_test.go
+++ b/eth/tracers/js/tracer_test.go
@@ -56,8 +56,10 @@ type dummyStatedb struct {
state.IntraBlockState
}
-func (*dummyStatedb) GetRefund() uint64 { return 1337 }
-func (*dummyStatedb) GetBalance(addr libcommon.Address) *uint256.Int { return &uint256.Int{} }
+func (*dummyStatedb) GetRefund() uint64 { return 1337 }
+func (*dummyStatedb) GetBalance(addr libcommon.Address) (*uint256.Int, error) {
+ return &uint256.Int{}, nil
+}
type vmContext struct {
blockCtx evmtypes.BlockContext
diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go
index 882bb51955b..9dbfe7d8ebc 100644
--- a/eth/tracers/logger/access_list_tracer.go
+++ b/eth/tracers/logger/access_list_tracer.go
@@ -222,7 +222,7 @@ func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint6
if op == vm.CREATE {
// contract address for CREATE can only be generated with state
if a.state != nil {
- nonce := a.state.GetNonce(caller)
+ nonce, _ := a.state.GetNonce(caller)
addr := crypto.CreateAddress(caller, nonce)
if _, ok := a.excl[addr]; !ok {
a.createdContracts[addr] = struct{}{}
@@ -240,7 +240,6 @@ func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint6
a.createdContracts[addr] = struct{}{}
}
}
-
}
func (*AccessListTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go
index e32084d263f..0a896748906 100644
--- a/eth/tracers/native/prestate.go
+++ b/eth/tracers/native/prestate.go
@@ -171,7 +171,7 @@ func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,
addr := libcommon.Address(stackData[stackLen-2].Bytes20())
t.lookupAccount(addr)
case op == vm.CREATE:
- nonce := t.env.IntraBlockState().GetNonce(caller)
+ nonce, _ := t.env.IntraBlockState().GetNonce(caller)
addr := crypto.CreateAddress(caller, nonce)
t.lookupAccount(addr)
t.created[addr] = true
@@ -203,12 +203,12 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) {
}
modified := false
postAccount := &account{Storage: make(map[libcommon.Hash]libcommon.Hash)}
- newBalance := t.env.IntraBlockState().GetBalance(addr).ToBig()
- newNonce := t.env.IntraBlockState().GetNonce(addr)
+ newBalance, _ := t.env.IntraBlockState().GetBalance(addr)
+ newNonce, _ := t.env.IntraBlockState().GetNonce(addr)
- if newBalance.Cmp(t.pre[addr].Balance) != 0 {
+ if newBalance.ToBig().Cmp(t.pre[addr].Balance) != 0 {
modified = true
- postAccount.Balance = newBalance
+ postAccount.Balance = newBalance.ToBig()
}
if newNonce != t.pre[addr].Nonce {
modified = true
@@ -216,7 +216,7 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) {
}
if !t.config.DisableCode {
- newCode := t.env.IntraBlockState().GetCode(addr)
+ newCode, _ := t.env.IntraBlockState().GetCode(addr)
if !bytes.Equal(newCode, t.pre[addr].Code) {
modified = true
postAccount.Code = newCode
@@ -292,13 +292,17 @@ func (t *prestateTracer) lookupAccount(addr libcommon.Address) {
return
}
+ balance, _ := t.env.IntraBlockState().GetBalance(addr)
+ nonce, _ := t.env.IntraBlockState().GetNonce(addr)
+ code, _ := t.env.IntraBlockState().GetCode(addr)
+
t.pre[addr] = &account{
- Balance: t.env.IntraBlockState().GetBalance(addr).ToBig(),
- Nonce: t.env.IntraBlockState().GetNonce(addr),
+ Balance: balance.ToBig(),
+ Nonce: nonce,
}
if !t.config.DisableCode {
- t.pre[addr].Code = t.env.IntraBlockState().GetCode(addr)
+ t.pre[addr].Code = code
}
if !t.config.DisableStorage {
t.pre[addr].Storage = make(map[libcommon.Hash]libcommon.Hash)
diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go
index 4fab7e5beaa..9e67064ba1f 100644
--- a/ethdb/privateapi/ethbackend.go
+++ b/ethdb/privateapi/ethbackend.go
@@ -275,15 +275,15 @@ func (s *EthBackendServer) TxnLookup(ctx context.Context, req *remote.TxnLookupR
}
defer tx.Rollback()
- blockNum, ok, err := s.blockReader.TxnLookup(ctx, tx, gointerfaces.ConvertH256ToHash(req.TxnHash))
+ blockNum, txNum, ok, err := s.blockReader.TxnLookup(ctx, tx, gointerfaces.ConvertH256ToHash(req.TxnHash))
if err != nil {
return nil, err
}
if !ok {
// Not a perfect solution, assumes there are no transactions in block 0
- return &remote.TxnLookupReply{BlockNumber: 0}, nil
+ return &remote.TxnLookupReply{BlockNumber: 0, TxNumber: txNum}, nil
}
- return &remote.TxnLookupReply{BlockNumber: blockNum}, nil
+ return &remote.TxnLookupReply{BlockNumber: blockNum, TxNumber: txNum}, nil
}
func (s *EthBackendServer) Block(ctx context.Context, req *remote.BlockRequest) (*remote.BlockReply, error) {
diff --git a/go.mod b/go.mod
index 40c3e76e5d8..2b8348ef6dd 100644
--- a/go.mod
+++ b/go.mod
@@ -53,19 +53,19 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/hashicorp/golang-lru/arc/v2 v2.0.7
github.com/hashicorp/golang-lru/v2 v2.0.7
- github.com/holiman/uint256 v1.3.1
+ github.com/holiman/uint256 v1.3.2
github.com/huandu/xstrings v1.5.0
github.com/huin/goupnp v1.3.0
github.com/jackpal/go-nat-pmp v1.0.2
github.com/jedib0t/go-pretty/v6 v6.5.9
github.com/json-iterator/go v1.1.12
github.com/julienschmidt/httprouter v1.3.0
- github.com/klauspost/compress v1.17.9
- github.com/libp2p/go-libp2p v0.34.0
+ github.com/klauspost/compress v1.17.11
+ github.com/libp2p/go-libp2p v0.37.2
github.com/libp2p/go-libp2p-mplex v0.9.0
github.com/libp2p/go-libp2p-pubsub v0.11.0
github.com/maticnetwork/crand v1.0.2
- github.com/multiformats/go-multiaddr v0.12.4
+ github.com/multiformats/go-multiaddr v0.13.0
github.com/nxadm/tail v1.4.11
github.com/pelletier/go-toml v1.9.5
github.com/pelletier/go-toml/v2 v2.2.3
@@ -115,6 +115,7 @@ require (
github.com/elastic/go-freelru v0.13.0 // indirect
github.com/erigontech/speedtest v0.0.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
+ github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@@ -123,6 +124,7 @@ require (
github.com/nyaosorg/go-windows-shortcut v0.0.0-20220529122037-8b0c89bca4c4 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
+ github.com/wlynxg/anet v0.0.5 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
@@ -167,7 +169,7 @@ require (
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
- github.com/elastic/gosigar v0.14.2 // indirect
+ github.com/elastic/gosigar v0.14.3 // indirect
github.com/erigontech/erigon-snapshot v1.3.1-0.20241023024258-f64407a77e8e // indirect
github.com/flynn/noise v1.1.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
@@ -175,15 +177,14 @@ require (
github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c // indirect
github.com/go-llsqlite/adapter v0.0.0-20230927005056-7f5ce7f0c916 // indirect
github.com/go-llsqlite/crawshaw v0.5.2-0.20240425034140-f30eb7704568 // indirect
- github.com/go-logr/logr v1.3.0 // indirect
+ github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/go-stack/stack v1.8.1
- github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gopacket v1.1.19 // indirect
- github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect
+ github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/ianlancetaylor/cgosymbolizer v0.0.0-20240503222823-736c933a666d // indirect
github.com/imdario/mergo v0.3.11 // indirect
@@ -191,12 +192,12 @@ require (
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
- github.com/klauspost/cpuid/v2 v2.2.7 // indirect
+ github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
- github.com/libp2p/go-flow-metrics v0.1.0 // indirect
+ github.com/libp2p/go-flow-metrics v0.2.0 // indirect
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
github.com/libp2p/go-mplex v0.7.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
@@ -209,7 +210,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
- github.com/miekg/dns v1.1.58 // indirect
+ github.com/miekg/dns v1.1.62 // indirect
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
@@ -222,40 +223,40 @@ require (
github.com/mschoch/smat v0.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
- github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
+ github.com/multiformats/go-multiaddr-dns v0.4.1 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
- github.com/multiformats/go-multistream v0.5.0 // indirect
+ github.com/multiformats/go-multistream v0.6.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
- github.com/onsi/ginkgo/v2 v2.15.0 // indirect
+ github.com/onsi/ginkgo/v2 v2.20.2 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
- github.com/pion/datachannel v1.5.6 // indirect
- github.com/pion/dtls/v2 v2.2.11 // indirect
- github.com/pion/ice/v2 v2.3.24 // indirect
- github.com/pion/interceptor v0.1.29 // indirect
+ github.com/pion/datachannel v1.5.9 // indirect
+ github.com/pion/dtls/v2 v2.2.12 // indirect
+ github.com/pion/ice/v2 v2.3.36 // indirect
+ github.com/pion/interceptor v0.1.37 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.12 // indirect
github.com/pion/rtcp v1.2.14 // indirect
- github.com/pion/rtp v1.8.6 // indirect
- github.com/pion/sctp v1.8.16 // indirect
+ github.com/pion/rtp v1.8.9 // indirect
+ github.com/pion/sctp v1.8.33 // indirect
github.com/pion/sdp/v3 v3.0.9 // indirect
- github.com/pion/srtp/v2 v2.0.18 // indirect
- github.com/pion/transport/v2 v2.2.5 // indirect
+ github.com/pion/srtp/v2 v2.0.20 // indirect
+ github.com/pion/transport/v2 v2.2.10 // indirect
github.com/pion/turn/v2 v2.1.6 // indirect
- github.com/pion/webrtc/v3 v3.2.40 // indirect
+ github.com/pion/webrtc/v3 v3.3.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.20.5
github.com/prometheus/client_model v0.6.1 // indirect
- github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/common v0.60.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
- github.com/quic-go/qpack v0.4.0 // indirect
- github.com/quic-go/quic-go v0.44.0 // indirect
- github.com/quic-go/webtransport-go v0.8.0 // indirect
+ github.com/quic-go/qpack v0.5.1 // indirect
+ github.com/quic-go/quic-go v0.48.2 // indirect
+ github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
@@ -275,14 +276,14 @@ require (
go.etcd.io/bbolt v1.3.6 // indirect
go.opentelemetry.io/otel v1.8.0 // indirect
go.opentelemetry.io/otel/trace v1.8.0 // indirect
- go.uber.org/dig v1.17.1 // indirect
- go.uber.org/fx v1.21.1 // indirect
+ go.uber.org/dig v1.18.0 // indirect
+ go.uber.org/fx v1.23.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/tools v0.26.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
- lukechampine.com/blake3 v1.2.1 // indirect
+ lukechampine.com/blake3 v1.3.0 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.55.3 // indirect
modernc.org/mathutil v1.6.0 // indirect
diff --git a/go.sum b/go.sum
index fbc4315e5a6..ad8fccd3067 100644
--- a/go.sum
+++ b/go.sum
@@ -255,8 +255,8 @@ github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8E
github.com/elastic/go-freelru v0.13.0 h1:TKKY6yCfNNNky7Pj9xZAOEpBcdNgZJfihEftOb55omg=
github.com/elastic/go-freelru v0.13.0/go.mod h1:bSdWT4M0lW79K8QbX6XY2heQYSCqD7THoYf82pT/H3I=
github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
-github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4=
-github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
+github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo=
+github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A=
github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -327,8 +327,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
-github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
@@ -338,8 +338,8 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
@@ -431,8 +431,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
-github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -472,8 +472,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
-github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs=
-github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
+github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
+github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
@@ -518,10 +518,10 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
-github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
-github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
+github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
+github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
@@ -544,10 +544,10 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
-github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
-github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
-github.com/libp2p/go-libp2p v0.34.0 h1:J+SL3DMz+zPz06OHSRt42GKA5n5hmwgY1l7ckLUz3+c=
-github.com/libp2p/go-libp2p v0.34.0/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ=
+github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw=
+github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc=
+github.com/libp2p/go-libp2p v0.37.2 h1:Irh+n9aDPTLt9wJYwtlHu6AhMUipbC1cGoJtOiBqI9c=
+github.com/libp2p/go-libp2p v0.37.2/go.mod h1:M8CRRywYkqC6xKHdZ45hmqVckBj5z4mRLIMLWReypz8=
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8=
@@ -586,9 +586,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
-github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
-github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
-github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
+github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
+github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
@@ -624,11 +623,10 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
-github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
-github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc=
-github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
-github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
-github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
+github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ=
+github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
+github.com/multiformats/go-multiaddr-dns v0.4.1 h1:whi/uCLbDS3mSEUMb1MsoT4uzUeZB0N32yzufqS0i5M=
+github.com/multiformats/go-multiaddr-dns v0.4.1/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
@@ -638,9 +636,8 @@ github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI1
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
-github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE=
-github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA=
-github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
+github.com/multiformats/go-multistream v0.6.0 h1:ZaHKbsL404720283o4c/IHQXiS6gb8qAN5EIJ4PN5EA=
+github.com/multiformats/go-multistream v0.6.0/go.mod h1:MOyoG5otO24cHIg8kf9QW2/NozURlkP/rvi2FQJyCPg=
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
@@ -658,11 +655,11 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
-github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
+github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
+github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
-github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
+github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
+github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
@@ -677,15 +674,15 @@ github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNH
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg=
-github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4=
+github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA=
+github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
-github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks=
-github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
-github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI=
-github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
-github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M=
-github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4=
+github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
+github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
+github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc=
+github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ=
+github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI=
+github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
@@ -696,32 +693,30 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9
github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=
github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
-github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw=
-github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
-github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA=
-github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY=
-github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE=
+github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk=
+github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw=
+github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM=
github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
-github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo=
-github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
+github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk=
+github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
-github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
-github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc=
-github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
+github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q=
+github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
-github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4=
-github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0=
+github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
+github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
-github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU=
-github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY=
+github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk=
+github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -750,8 +745,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
-github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA=
+github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -768,12 +763,12 @@ github.com/prysmaticlabs/gohashtree v0.0.3-alpha.0.20230502123415-aafd8b3ca202 h
github.com/prysmaticlabs/gohashtree v0.0.3-alpha.0.20230502123415-aafd8b3ca202/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk=
github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
-github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
-github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
-github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=
-github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
-github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=
-github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM=
+github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
+github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
+github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
+github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
+github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
+github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
@@ -869,7 +864,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -904,6 +898,9 @@ github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49u
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
+github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
+github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
+github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg=
@@ -932,10 +929,10 @@ go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRM
go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY=
go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc=
-go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
-go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0=
-go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48=
+go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
+go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
+go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
+go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -967,11 +964,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
-golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
-golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
-golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1062,11 +1056,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
-golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
-golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1144,7 +1135,6 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1164,11 +1154,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1177,11 +1164,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
-golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
-golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1193,7 +1177,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
@@ -1412,8 +1395,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
-lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
+lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
+lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
diff --git a/migrations/migrations.go b/migrations/migrations.go
index 211d77f860e..5fc2d4ed99b 100644
--- a/migrations/migrations.go
+++ b/migrations/migrations.go
@@ -55,6 +55,7 @@ var migrations = map[kv.Label][]Migration{
ProhibitNewDownloadsLock,
ProhibitNewDownloadsLock2,
ClearBorTables,
+ ResetStageTxnLookup,
},
kv.TxPoolDB: {},
kv.SentryDB: {},
diff --git a/migrations/reset_stage_txn_lookup.go b/migrations/reset_stage_txn_lookup.go
new file mode 100644
index 00000000000..d4c9e7cb8b2
--- /dev/null
+++ b/migrations/reset_stage_txn_lookup.go
@@ -0,0 +1,47 @@
+// Copyright 2024 The Erigon Authors
+// This file is part of Erigon.
+//
+// Erigon is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Erigon is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with Erigon. If not, see .
+
+package migrations
+
+import (
+ "context"
+ "github.com/erigontech/erigon-lib/common/datadir"
+ "github.com/erigontech/erigon-lib/kv"
+ "github.com/erigontech/erigon-lib/log/v3"
+ reset2 "github.com/erigontech/erigon/core/rawdb/rawdbreset"
+)
+
+// for new txn index.
+var ResetStageTxnLookup = Migration{
+ Name: "reset_stage_txn_lookup",
+ Up: func(db kv.RwDB, dirs datadir.Dirs, progress []byte, BeforeCommit Callback, logger log.Logger) (err error) {
+ tx, err := db.BeginRw(context.Background())
+ if err != nil {
+ return err
+ }
+ defer tx.Rollback()
+
+ if err := BeforeCommit(tx, nil, true); err != nil {
+ return err
+ }
+
+ if err := reset2.ResetTxLookup(tx); err != nil {
+ return err
+ }
+
+ return tx.Commit()
+ },
+}
diff --git a/params/version.go b/params/version.go
index b2b6c14433d..5cba261ef11 100644
--- a/params/version.go
+++ b/params/version.go
@@ -37,9 +37,11 @@ const (
VersionMajor = 3 // Major version component of the current release
VersionMinor = 0 // Minor version component of the current release
VersionMicro = 0 // Patch version component of the current release
- VersionModifier = "alpha5" // Modifier component of the current release
+ VersionModifier = "alpha6" // Modifier component of the current release
VersionKeyCreated = "ErigonVersionCreated"
VersionKeyFinished = "ErigonVersionFinished"
+ ClientName = "erigon"
+ ClientCode = "EG"
)
// Version holds the textual version string.
diff --git a/polygon/bor/bor.go b/polygon/bor/bor.go
index 36337ac941c..1bba50d515d 100644
--- a/polygon/bor/bor.go
+++ b/polygon/bor/bor.go
@@ -1673,22 +1673,42 @@ func (c *Bor) getNextHeimdallSpanForTest(
}
// BorTransfer transfer in Bor
-func BorTransfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) {
+func BorTransfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) error {
// get inputs before
- input1 := db.GetBalance(sender).Clone()
- input2 := db.GetBalance(recipient).Clone()
-
+ input1, err := db.GetBalance(sender)
+ if err != nil {
+ return err
+ }
+ input1 = input1.Clone()
+ input2, err := db.GetBalance(recipient)
+ if err != nil {
+ return err
+ }
+ input2 = input2.Clone()
if !bailout {
- db.SubBalance(sender, amount, tracing.BalanceChangeTransfer)
+ err := db.SubBalance(sender, amount, tracing.BalanceChangeTransfer)
+ if err != nil {
+ return err
+ }
+ }
+ err = db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer)
+ if err != nil {
+ return err
}
- db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer)
-
// get outputs after
- output1 := db.GetBalance(sender).Clone()
- output2 := db.GetBalance(recipient).Clone()
-
+ output1, err := db.GetBalance(sender)
+ if err != nil {
+ return err
+ }
+ output1 = output1.Clone()
+ output2, err := db.GetBalance(recipient)
+ if err != nil {
+ return err
+ }
+ output2 = output2.Clone()
// add transfer log into state
addTransferLog(db, transferLogSig, sender, recipient, amount, input1, input2, output1, output2)
+ return nil
}
func (c *Bor) GetTransferFunc() evmtypes.TransferFunc {
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index f2822f97f66..b945526201e 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -319,9 +319,18 @@ func (bt *BlockTest) validatePostState(statedb *state.IntraBlockState) error {
// validate post state accounts in test file against what we have in state db
for addr, acct := range bt.json.Post {
// address is indirectly verified by the other fields, as it's the db key
- code2 := statedb.GetCode(addr)
- balance2 := statedb.GetBalance(addr)
- nonce2 := statedb.GetNonce(addr)
+ code2, err := statedb.GetCode(addr)
+ if err != nil {
+ return err
+ }
+ balance2, err := statedb.GetBalance(addr)
+ if err != nil {
+ return err
+ }
+ nonce2, err := statedb.GetNonce(addr)
+ if err != nil {
+ return err
+ }
if nonce2 != acct.Nonce {
return fmt.Errorf("account nonce mismatch for addr: %x want: %d have: %d", addr, acct.Nonce, nonce2)
}
diff --git a/tests/contracts/gen.go b/tests/contracts/gen.go
index 1f74de20eb2..a35d5623d42 100644
--- a/tests/contracts/gen.go
+++ b/tests/contracts/gen.go
@@ -6,4 +6,4 @@ package contracts
// selfDestructor.sol
//go:generate solc --allow-paths ., --abi --bin --overwrite --optimize -o build selfDestructor.sol
-//go:generate abigen -abi build/selfdestructor.abi -bin build/selfdestructor.bin -pkg contracts -type selfDestructor -out ./gen_selfDestructor.go
+//go:generate abigen -abi build/selfDestructor.abi -bin build/selfDestructor.bin -pkg contracts -type selfDestructor -out ./gen_selfDestructor.go
diff --git a/tests/contracts/gen_selfDestructor.go b/tests/contracts/gen_selfDestructor.go
index d6639e8c0b4..657d06ada33 100644
--- a/tests/contracts/gen_selfDestructor.go
+++ b/tests/contracts/gen_selfDestructor.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// SelfDestructorABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeploySelfDestructor(auth *bind.TransactOpts, backend bind.ContractBackend)
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(SelfDestructorBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(SelfDestructorBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
diff --git a/tests/contracts/gen_testcontract.go b/tests/contracts/gen_testcontract.go
index 544f65b6c3b..f6fe4b0bda7 100644
--- a/tests/contracts/gen_testcontract.go
+++ b/tests/contracts/gen_testcontract.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,13 +26,15 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// TestcontractABI is the input ABI used to generate the binding from.
const TestcontractABI = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balances\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"create\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"createAndException\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"createAndRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"remove\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"removeAndException\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"removeAndRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"updateAndException\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"updateAndRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
// TestcontractBin is the compiled bytecode used for deploying new contracts.
-var TestcontractBin = "0x608060405234801561001057600080fd5b5033600090815260208190526040902060649055610208806100336000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063c2ce0ef711610066578063c2ce0ef71461010a578063c53e5ae314610127578063cb946a0714610127578063d592ed1f14610144578063f64c050d1461010a5761009e565b806327e235e3146100a3578063660cc200146100db578063780900dc146100e557806382ab890a146100e5578063a7f4377914610102575b600080fd5b6100c9600480360360208110156100b957600080fd5b50356001600160a01b031661014c565b60408051918252519081900360200190f35b6100e361015e565b005b6100e3600480360360208110156100fb57600080fd5b5035610170565b6100e3610182565b6100e36004803603602081101561012057600080fd5b5035610194565b6100e36004803603602081101561013d57600080fd5b50356101a8565b6100e36101bd565b60006020819052908152604090205481565b33600090815260208190526040812055fe5b33600090815260208190526040902055565b33600090815260208190526040812055565b336000908152602081905260409020819055fe5b33600090815260208190526040812082905580fd5b33600090815260208190526040812081905580fdfea2646970667358221220c40698b47133056d15d4a84d769c07a1f24008b50347105be970e1f0191ca44f64736f6c63430007020033"
+var TestcontractBin = "0x608060405234801561001057600080fd5b503360009081526020819052604090206064905561023a806100336000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063c2ce0ef711610066578063c2ce0ef714610114578063c53e5ae314610127578063cb946a0714610127578063d592ed1f1461013a578063f64c050d1461011457600080fd5b806327e235e3146100a3578063660cc200146100d5578063780900dc146100df57806382ab890a146100df578063a7f43779146100ff575b600080fd5b6100c36100b13660046101a5565b60006020819052908152604090205481565b60405190815260200160405180910390f35b6100dd610142565b005b6100dd6100ed3660046101d5565b33600090815260208190526040902055565b6100dd33600090815260208190526040812055565b6100dd6101223660046101d5565b61015c565b6100dd6101353660046101d5565b610179565b6100dd610190565b3360009081526020819052604081205561015a6101ee565b565b3360009081526020819052604090208190556101766101ee565b50565b336000908152602081905260408120829055819080fd5b33600090815260208190526040812081905580fd5b6000602082840312156101b757600080fd5b81356001600160a01b03811681146101ce57600080fd5b9392505050565b6000602082840312156101e757600080fd5b5035919050565b634e487b7160e01b600052600160045260246000fdfea2646970667358221220cbc0ec1bd2504a9e5d6a3f3a8b92de36a1af219062eec962f407d937d0acadc664736f6c63430008130033"
// DeployTestcontract deploys a new Ethereum contract, binding an instance of Testcontract to it.
func DeployTestcontract(auth *bind.TransactOpts, backend bind.ContractBackend) (libcommon.Address, types.Transaction, *Testcontract, error) {
@@ -41,7 +43,7 @@ func DeployTestcontract(auth *bind.TransactOpts, backend bind.ContractBackend) (
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TestcontractBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(TestcontractBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
@@ -409,3 +411,225 @@ func (_Testcontract *TestcontractSession) UpdateAndRevert(newBalance *big.Int) (
func (_Testcontract *TestcontractTransactorSession) UpdateAndRevert(newBalance *big.Int) (types.Transaction, error) {
return _Testcontract.Contract.UpdateAndRevert(&_Testcontract.TransactOpts, newBalance)
}
+
+// TestcontractCreateParams is an auto generated read-only Go binding of transcaction calldata params
+type TestcontractCreateParams struct {
+ Param_newBalance *big.Int
+}
+
+// Parse Create method from calldata of a transaction
+//
+// Solidity: function create(uint256 newBalance) returns()
+func ParseTestcontractCreateParams(calldata []byte) (*TestcontractCreateParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TestcontractABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["create"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack create params data: %w", err)
+ }
+
+ var paramsResult = new(TestcontractCreateParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &TestcontractCreateParams{
+ Param_newBalance: out0,
+ }, nil
+}
+
+// TestcontractCreateAndExceptionParams is an auto generated read-only Go binding of transcaction calldata params
+type TestcontractCreateAndExceptionParams struct {
+ Param_newBalance *big.Int
+}
+
+// Parse CreateAndException method from calldata of a transaction
+//
+// Solidity: function createAndException(uint256 newBalance) returns()
+func ParseTestcontractCreateAndExceptionParams(calldata []byte) (*TestcontractCreateAndExceptionParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TestcontractABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["createAndException"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack createAndException params data: %w", err)
+ }
+
+ var paramsResult = new(TestcontractCreateAndExceptionParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &TestcontractCreateAndExceptionParams{
+ Param_newBalance: out0,
+ }, nil
+}
+
+// TestcontractCreateAndRevertParams is an auto generated read-only Go binding of transcaction calldata params
+type TestcontractCreateAndRevertParams struct {
+ Param_newBalance *big.Int
+}
+
+// Parse CreateAndRevert method from calldata of a transaction
+//
+// Solidity: function createAndRevert(uint256 newBalance) returns()
+func ParseTestcontractCreateAndRevertParams(calldata []byte) (*TestcontractCreateAndRevertParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TestcontractABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["createAndRevert"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack createAndRevert params data: %w", err)
+ }
+
+ var paramsResult = new(TestcontractCreateAndRevertParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &TestcontractCreateAndRevertParams{
+ Param_newBalance: out0,
+ }, nil
+}
+
+// TestcontractUpdateParams is an auto generated read-only Go binding of transcaction calldata params
+type TestcontractUpdateParams struct {
+ Param_newBalance *big.Int
+}
+
+// Parse Update method from calldata of a transaction
+//
+// Solidity: function update(uint256 newBalance) returns()
+func ParseTestcontractUpdateParams(calldata []byte) (*TestcontractUpdateParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TestcontractABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["update"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack update params data: %w", err)
+ }
+
+ var paramsResult = new(TestcontractUpdateParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &TestcontractUpdateParams{
+ Param_newBalance: out0,
+ }, nil
+}
+
+// TestcontractUpdateAndExceptionParams is an auto generated read-only Go binding of transcaction calldata params
+type TestcontractUpdateAndExceptionParams struct {
+ Param_newBalance *big.Int
+}
+
+// Parse UpdateAndException method from calldata of a transaction
+//
+// Solidity: function updateAndException(uint256 newBalance) returns()
+func ParseTestcontractUpdateAndExceptionParams(calldata []byte) (*TestcontractUpdateAndExceptionParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TestcontractABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["updateAndException"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack updateAndException params data: %w", err)
+ }
+
+ var paramsResult = new(TestcontractUpdateAndExceptionParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &TestcontractUpdateAndExceptionParams{
+ Param_newBalance: out0,
+ }, nil
+}
+
+// TestcontractUpdateAndRevertParams is an auto generated read-only Go binding of transcaction calldata params
+type TestcontractUpdateAndRevertParams struct {
+ Param_newBalance *big.Int
+}
+
+// Parse UpdateAndRevert method from calldata of a transaction
+//
+// Solidity: function updateAndRevert(uint256 newBalance) returns()
+func ParseTestcontractUpdateAndRevertParams(calldata []byte) (*TestcontractUpdateAndRevertParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TestcontractABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["updateAndRevert"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack updateAndRevert params data: %w", err)
+ }
+
+ var paramsResult = new(TestcontractUpdateAndRevertParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &TestcontractUpdateAndRevertParams{
+ Param_newBalance: out0,
+ }, nil
+}
diff --git a/tests/difficulty_test_util.go b/tests/difficulty_test_util.go
index 7fcc1f09b8b..5cf7f86a5ec 100644
--- a/tests/difficulty_test_util.go
+++ b/tests/difficulty_test_util.go
@@ -47,7 +47,7 @@ type difficultyTestMarshaling struct {
ParentDifficulty *math.HexOrDecimal256
CurrentTimestamp math.HexOrDecimal64
CurrentDifficulty *math.HexOrDecimal256
- ParentUncles uint64
+ ParentUncles math.HexOrDecimal64
CurrentBlockNumber math.HexOrDecimal64
}
diff --git a/tests/gen_stenv.go b/tests/gen_stenv.go
index 02bbd20fa1c..f911db30eac 100644
--- a/tests/gen_stenv.go
+++ b/tests/gen_stenv.go
@@ -9,8 +9,6 @@ import (
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/math"
-
- common0 "github.com/erigontech/erigon-lib/common"
)
var _ = (*stEnvMarshaling)(nil)
@@ -18,17 +16,17 @@ var _ = (*stEnvMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (s stEnv) MarshalJSON() ([]byte, error) {
type stEnv struct {
- Coinbase common0.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"`
- Random *math.HexOrDecimal256 `json:"currentRandom" gencodec:"optional"`
- GasLimit math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
- Number math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
- Timestamp math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
- BaseFee *math.HexOrDecimal256 `json:"currentBaseFee" gencodec:"optional"`
- ExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas" gencodec:"optional"`
+ Coinbase common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"`
+ Random *math.HexOrDecimal256 `json:"currentRandom" gencodec:"optional"`
+ GasLimit math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
+ Number math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
+ Timestamp math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
+ BaseFee *math.HexOrDecimal256 `json:"currentBaseFee" gencodec:"optional"`
+ ExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas" gencodec:"optional"`
}
var enc stEnv
- enc.Coinbase = common0.UnprefixedAddress(s.Coinbase)
+ enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
enc.Difficulty = (*math.HexOrDecimal256)(s.Difficulty)
enc.Random = (*math.HexOrDecimal256)(s.Random)
enc.GasLimit = math.HexOrDecimal64(s.GasLimit)
@@ -42,14 +40,14 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
// UnmarshalJSON unmarshals from JSON.
func (s *stEnv) UnmarshalJSON(input []byte) error {
type stEnv struct {
- Coinbase *common0.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"`
- Random *math.HexOrDecimal256 `json:"currentRandom" gencodec:"optional"`
- GasLimit *math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
- Number *math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
- Timestamp *math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
- BaseFee *math.HexOrDecimal256 `json:"currentBaseFee" gencodec:"optional"`
- ExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas" gencodec:"optional"`
+ Coinbase *common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"`
+ Random *math.HexOrDecimal256 `json:"currentRandom" gencodec:"optional"`
+ GasLimit *math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
+ Number *math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
+ Timestamp *math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
+ BaseFee *math.HexOrDecimal256 `json:"currentBaseFee" gencodec:"optional"`
+ ExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas" gencodec:"optional"`
}
var dec stEnv
if err := json.Unmarshal(input, &dec); err != nil {
diff --git a/tests/statedb_chain_test.go b/tests/statedb_chain_test.go
index 7449ea92215..525b3c0f12c 100644
--- a/tests/statedb_chain_test.go
+++ b/tests/statedb_chain_test.go
@@ -105,10 +105,18 @@ func TestSelfDestructReceive(t *testing.T) {
if err := m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ exist, err := st.Exist(address)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("expected contractAddress to not exist before block 0", contractAddress.String())
}
return nil
@@ -131,13 +139,25 @@ func TestSelfDestructReceive(t *testing.T) {
// and that means that the state of the accounts written in the first block was correct.
// This test checks that the storage root of the account is properly set to the root of the empty tree
st := state.New(m.NewStateReader(tx))
- if !st.Exist(address) {
+ exist, err := st.Exist(address)
+ if err != nil {
+ t.Error(err)
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if !st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ t.Error(err)
+ }
+ if !exist {
t.Error("expected contractAddress to exist at the block 2", contractAddress.String())
}
- if len(st.GetCode(contractAddress)) != 0 {
+ code, err := st.GetCode(contractAddress)
+ if err != nil {
+ t.Error(err)
+ }
+ if len(code) != 0 {
t.Error("expected empty code in contract at block 2", contractAddress.String())
}
return nil
diff --git a/tests/statedb_insert_chain_transaction_test.go b/tests/statedb_insert_chain_transaction_test.go
index e9f28a610d2..a2d3eddd264 100644
--- a/tests/statedb_insert_chain_transaction_test.go
+++ b/tests/statedb_insert_chain_transaction_test.go
@@ -93,17 +93,33 @@ func TestInsertIncorrectStateRootDifferentAccounts(t *testing.T) {
defer tx.Rollback()
st := state.New(m.NewStateReader(tx))
- if !st.Exist(to) {
+ exist, err := st.Exist(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if balance := st.GetBalance(from); balance.Uint64() != 1000000000 {
+ balance, err := st.GetBalance(from)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 1000000000 {
t.Fatalf("got %v, expected %v", balance, 1000000000)
}
- if balance := st.GetBalance(data.addresses[1]); balance.Uint64() != 999995000 {
+ balance, err = st.GetBalance(data.addresses[1])
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 999995000 {
t.Fatalf("got %v, expected %v", balance, 999995000)
}
- if balance := st.GetBalance(to); balance.Uint64() != 5000 {
+ balance, err = st.GetBalance(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 5000 {
t.Fatalf("got %v, expected %v", balance, 5000)
}
}
@@ -161,14 +177,26 @@ func TestInsertIncorrectStateRootSameAccount(t *testing.T) {
defer tx.Rollback()
st := state.New(m.NewStateReader(tx))
- if !st.Exist(to) {
+ exist, err := st.Exist(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if balance := st.GetBalance(from); balance.Uint64() != 999995000 {
+ balance, err := st.GetBalance(from)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 999995000 {
t.Fatalf("got %v, expected %v", balance, 999995000)
}
- if balance := st.GetBalance(to); balance.Uint64() != 5000 {
+ balance, err = st.GetBalance(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 5000 {
t.Fatalf("got %v, expected %v", balance, 5000)
}
}
@@ -223,14 +251,26 @@ func TestInsertIncorrectStateRootSameAccountSameAmount(t *testing.T) {
defer tx.Rollback()
st := state.New(m.NewStateReader(tx))
- if !st.Exist(to) {
+ exist, err := st.Exist(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if balance := st.GetBalance(from); balance.Uint64() != 999999000 {
+ balance, err := st.GetBalance(from)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 999999000 {
t.Fatalf("got %v, expected %v", balance, 999999000)
}
- if balance := st.GetBalance(to); balance.Uint64() != 1000 {
+ balance, err = st.GetBalance(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 1000 {
t.Fatalf("got %v, expected %v", balance, 1000)
}
}
@@ -285,14 +325,26 @@ func TestInsertIncorrectStateRootAllFundsRoot(t *testing.T) {
defer tx.Rollback()
st := state.New(m.NewStateReader(tx))
- if !st.Exist(to) {
+ exist, err := st.Exist(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if balance := st.GetBalance(from); balance.Uint64() != 2000 {
+ balance, err := st.GetBalance(from)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 2000 {
t.Fatalf("got %v, expected %v", balance, 2000)
}
- if balance := st.GetBalance(to); balance.Uint64() != 1000 {
+ balance, err = st.GetBalance(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 1000 {
t.Fatalf("got %v, expected %v", balance, 1000)
}
}
@@ -347,14 +399,26 @@ func TestInsertIncorrectStateRootAllFunds(t *testing.T) {
defer tx.Rollback()
st := state.New(m.NewStateReader(tx))
- if !st.Exist(to) {
+ exist, err := st.Exist(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if balance := st.GetBalance(from); balance.Uint64() != 2000 {
+ balance, err := st.GetBalance(from)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 2000 {
t.Fatalf("got %v, expected %v", balance, 2000)
}
- if balance := st.GetBalance(to); balance.Uint64() != 1000 {
+ balance, err = st.GetBalance(to)
+ if err != nil {
+ t.Error(err)
+ }
+ if balance.Uint64() != 1000 {
t.Fatalf("got %v, expected %v", balance, 1000)
}
}
@@ -388,11 +452,18 @@ func TestAccountDeployIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
-
- if st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String())
}
return nil
@@ -411,11 +482,19 @@ func TestAccountDeployIncorrectRoot(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("expected contractAddress to not exist at the block 1", contractAddress.Hash().String())
}
return nil
@@ -429,11 +508,19 @@ func TestAccountDeployIncorrectRoot(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if !st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected contractAddress to not exist at the block 1", contractAddress.Hash().String())
}
return nil
@@ -475,11 +562,19 @@ func TestAccountCreateIncorrectRoot(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String())
}
@@ -493,11 +588,19 @@ func TestAccountCreateIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if !st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected contractAddress to exist at the block 2", contractAddress.Hash().String())
}
@@ -559,11 +662,19 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String())
}
@@ -578,11 +689,19 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if !st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected contractAddress to exist at the block 2", contractAddress.Hash().String())
}
return nil
@@ -648,11 +767,19 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String())
}
return nil
@@ -666,11 +793,19 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) {
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(m.NewStateReader(tx))
- if !st.Exist(from) {
+ exist, err := st.Exist(from)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected account to exist")
}
- if !st.Exist(contractAddress) {
+ exist, err = st.Exist(contractAddress)
+ if err != nil {
+ return err
+ }
+ if !exist {
t.Error("expected contractAddress to exist at the block 1", contractAddress.Hash().String())
}
return nil
diff --git a/turbo/engineapi/engine_api_methods.go b/turbo/engineapi/engine_api_methods.go
new file mode 100644
index 00000000000..43e9b98bce2
--- /dev/null
+++ b/turbo/engineapi/engine_api_methods.go
@@ -0,0 +1,168 @@
+package engineapi
+
+import (
+ "context"
+ "encoding/binary"
+
+ libcommon "github.com/erigontech/erigon-lib/common"
+ "github.com/erigontech/erigon-lib/common/hexutil"
+ "github.com/erigontech/erigon-lib/common/hexutility"
+ "github.com/erigontech/erigon/params"
+
+ "github.com/erigontech/erigon/cl/clparams"
+ "github.com/erigontech/erigon/turbo/engineapi/engine_types"
+)
+
+var ourCapabilities = []string{
+ "engine_forkchoiceUpdatedV1",
+ "engine_forkchoiceUpdatedV2",
+ "engine_forkchoiceUpdatedV3",
+ "engine_newPayloadV1",
+ "engine_newPayloadV2",
+ "engine_newPayloadV3",
+ "engine_newPayloadV4",
+ "engine_getPayloadV1",
+ "engine_getPayloadV2",
+ "engine_getPayloadV3",
+ "engine_getPayloadV4",
+ "engine_getPayloadBodiesByHashV1",
+ "engine_getPayloadBodiesByRangeV1",
+ "engine_getClientVersionV1",
+}
+
+// Returns the most recent version of the payload(for the payloadID) at the time of receiving the call
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_getpayloadv1
+func (e *EngineServer) GetPayloadV1(ctx context.Context, payloadId hexutility.Bytes) (*engine_types.ExecutionPayload, error) {
+ if e.caplin {
+ e.logger.Crit(caplinEnabledLog)
+ return nil, errCaplinEnabled
+ }
+ e.engineLogSpamer.RecordRequest()
+
+ decodedPayloadId := binary.BigEndian.Uint64(payloadId)
+ e.logger.Info("Received GetPayloadV1", "payloadId", decodedPayloadId)
+
+ response, err := e.getPayload(ctx, decodedPayloadId, clparams.BellatrixVersion)
+ if err != nil {
+ return nil, err
+ }
+
+ return response.ExecutionPayload, nil
+}
+
+// Same as [GetPayloadV1] with addition of blockValue
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadv2
+func (e *EngineServer) GetPayloadV2(ctx context.Context, payloadID hexutility.Bytes) (*engine_types.GetPayloadResponse, error) {
+ decodedPayloadId := binary.BigEndian.Uint64(payloadID)
+ e.logger.Info("Received GetPayloadV2", "payloadId", decodedPayloadId)
+ return e.getPayload(ctx, decodedPayloadId, clparams.CapellaVersion)
+}
+
+// Same as [GetPayloadV2], with addition of blobsBundle containing valid blobs, commitments, proofs
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#engine_getpayloadv3
+func (e *EngineServer) GetPayloadV3(ctx context.Context, payloadID hexutility.Bytes) (*engine_types.GetPayloadResponse, error) {
+ decodedPayloadId := binary.BigEndian.Uint64(payloadID)
+ e.logger.Info("Received GetPayloadV3", "payloadId", decodedPayloadId)
+ return e.getPayload(ctx, decodedPayloadId, clparams.DenebVersion)
+}
+
+// Same as [GetPayloadV3], but returning ExecutionPayloadV4 (= ExecutionPayloadV3 + requests)
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#engine_getpayloadv4
+func (e *EngineServer) GetPayloadV4(ctx context.Context, payloadID hexutility.Bytes) (*engine_types.GetPayloadResponse, error) {
+ decodedPayloadId := binary.BigEndian.Uint64(payloadID)
+ e.logger.Info("Received GetPayloadV4", "payloadId", decodedPayloadId)
+ return e.getPayload(ctx, decodedPayloadId, clparams.ElectraVersion)
+}
+
+// Updates the forkchoice state after validating the headBlockHash
+// Additionally, builds and returns a unique identifier for an initial version of a payload
+// (asynchronously updated with transactions), if payloadAttributes is not nil and passes validation
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_forkchoiceupdatedv1
+func (e *EngineServer) ForkchoiceUpdatedV1(ctx context.Context, forkChoiceState *engine_types.ForkChoiceState, payloadAttributes *engine_types.PayloadAttributes) (*engine_types.ForkChoiceUpdatedResponse, error) {
+ return e.forkchoiceUpdated(ctx, forkChoiceState, payloadAttributes, clparams.BellatrixVersion)
+}
+
+// Same as, and a replacement for, [ForkchoiceUpdatedV1], post Shanghai
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_forkchoiceupdatedv2
+func (e *EngineServer) ForkchoiceUpdatedV2(ctx context.Context, forkChoiceState *engine_types.ForkChoiceState, payloadAttributes *engine_types.PayloadAttributes) (*engine_types.ForkChoiceUpdatedResponse, error) {
+ return e.forkchoiceUpdated(ctx, forkChoiceState, payloadAttributes, clparams.CapellaVersion)
+}
+
+// Successor of [ForkchoiceUpdatedV2] post Cancun, with stricter check on params
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#engine_forkchoiceupdatedv3
+func (e *EngineServer) ForkchoiceUpdatedV3(ctx context.Context, forkChoiceState *engine_types.ForkChoiceState, payloadAttributes *engine_types.PayloadAttributes) (*engine_types.ForkChoiceUpdatedResponse, error) {
+ return e.forkchoiceUpdated(ctx, forkChoiceState, payloadAttributes, clparams.DenebVersion)
+}
+
+// NewPayloadV1 processes new payloads (blocks) from the beacon chain without withdrawals.
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_newpayloadv1
+func (e *EngineServer) NewPayloadV1(ctx context.Context, payload *engine_types.ExecutionPayload) (*engine_types.PayloadStatus, error) {
+ return e.newPayload(ctx, payload, nil, nil, nil, clparams.BellatrixVersion)
+}
+
+// NewPayloadV2 processes new payloads (blocks) from the beacon chain with withdrawals.
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_newpayloadv2
+func (e *EngineServer) NewPayloadV2(ctx context.Context, payload *engine_types.ExecutionPayload) (*engine_types.PayloadStatus, error) {
+ return e.newPayload(ctx, payload, nil, nil, nil, clparams.CapellaVersion)
+}
+
+// NewPayloadV3 processes new payloads (blocks) from the beacon chain with withdrawals & blob gas.
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#engine_newpayloadv3
+func (e *EngineServer) NewPayloadV3(ctx context.Context, payload *engine_types.ExecutionPayload,
+ expectedBlobHashes []libcommon.Hash, parentBeaconBlockRoot *libcommon.Hash) (*engine_types.PayloadStatus, error) {
+ return e.newPayload(ctx, payload, expectedBlobHashes, parentBeaconBlockRoot, nil, clparams.DenebVersion)
+}
+
+// NewPayloadV4 processes new payloads (blocks) from the beacon chain with withdrawals, blob gas and requests.
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#engine_newpayloadv4
+func (e *EngineServer) NewPayloadV4(ctx context.Context, payload *engine_types.ExecutionPayload,
+ expectedBlobHashes []libcommon.Hash, parentBeaconBlockRoot *libcommon.Hash, executionRequests []hexutility.Bytes) (*engine_types.PayloadStatus, error) {
+ // TODO(racytech): add proper version or refactor this part
+ // add all version ralated checks here so the newpayload doesn't have to deal with checks
+ return e.newPayload(ctx, payload, expectedBlobHashes, parentBeaconBlockRoot, executionRequests, clparams.ElectraVersion)
+}
+
+// Returns an array of execution payload bodies referenced by their block hashes
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadbodiesbyhashv1
+func (e *EngineServer) GetPayloadBodiesByHashV1(ctx context.Context, hashes []libcommon.Hash) ([]*engine_types.ExecutionPayloadBody, error) {
+ return e.getPayloadBodiesByHash(ctx, hashes)
+}
+
+// Returns an ordered (as per canonical chain) array of execution payload bodies, with corresponding execution block numbers from "start", up to "count"
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadbodiesbyrangev1
+func (e *EngineServer) GetPayloadBodiesByRangeV1(ctx context.Context, start, count hexutil.Uint64) ([]*engine_types.ExecutionPayloadBody, error) {
+ return e.getPayloadBodiesByRange(ctx, uint64(start), uint64(count))
+}
+
+// Returns the node's code and commit details in a slice
+// See https://github.com/ethereum/execution-apis/blob/main/src/engine/identification.md#engine_getclientversionv1
+func (e *EngineServer) GetClientVersionV1(ctx context.Context, callerVersion *engine_types.ClientVersionV1) ([]engine_types.ClientVersionV1, error) {
+ if callerVersion != nil {
+ e.logger.Info("[GetClientVersionV1] Received request from" + callerVersion.String())
+ }
+ commitBytes := [4]byte{}
+ c := []byte(params.GitCommit)
+ if len(c) >= 4 {
+ copy(commitBytes[:], c[0:4])
+ }
+ result := make([]engine_types.ClientVersionV1, 1)
+ result[0] = engine_types.ClientVersionV1{
+ Code: params.ClientCode,
+ Name: params.ClientName,
+ Version: params.Version,
+ Commit: commitBytes,
+ }
+ return result, nil
+}
+
+func (e *EngineServer) ExchangeCapabilities(fromCl []string) []string {
+ e.engineLogSpamer.RecordRequest()
+ missingOurs := compareCapabilities(fromCl, ourCapabilities)
+ missingCl := compareCapabilities(ourCapabilities, fromCl)
+
+ if len(missingCl) > 0 || len(missingOurs) > 0 {
+ e.logger.Debug("ExchangeCapabilities mismatches", "cl_unsupported", missingCl, "erigon_unsupported", missingOurs)
+ }
+
+ return ourCapabilities
+}
diff --git a/turbo/engineapi/engine_logs_spammer/engine_log_spammer.go b/turbo/engineapi/engine_logs_spammer/engine_log_spammer.go
new file mode 100644
index 00000000000..431aa850d3e
--- /dev/null
+++ b/turbo/engineapi/engine_logs_spammer/engine_log_spammer.go
@@ -0,0 +1,52 @@
+package engine_logs_spammer
+
+import (
+ "context"
+ "sync/atomic"
+ "time"
+
+ "github.com/erigontech/erigon-lib/chain"
+ "github.com/erigontech/erigon-lib/log/v3"
+)
+
+type EngineLogsSpammer struct {
+ lastRequestTime atomic.Value
+ logger log.Logger
+ chainConfig *chain.Config
+}
+
+func NewEngineLogsSpammer(logger log.Logger, chainConfig *chain.Config) *EngineLogsSpammer {
+ lastRequestTimeAtomic := atomic.Value{}
+ lastRequestTimeAtomic.Store(time.Now())
+ return &EngineLogsSpammer{
+ logger: logger,
+ chainConfig: chainConfig,
+ lastRequestTime: lastRequestTimeAtomic,
+ }
+}
+
+func (e *EngineLogsSpammer) Start(ctx context.Context) {
+ e.lastRequestTime.Store(time.Now())
+ logSpamInterval := 20 * time.Second
+ if !e.chainConfig.TerminalTotalDifficultyPassed {
+ return
+ }
+ go func() {
+ intervalSpam := time.NewTicker(logSpamInterval)
+ defer intervalSpam.Stop()
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case <-intervalSpam.C:
+ if time.Since(e.lastRequestTime.Load().(time.Time)) > logSpamInterval {
+ e.logger.Warn("flag --externalcl was provided, but no CL seems to be connected.")
+ }
+ }
+ }
+ }()
+}
+
+func (e *EngineLogsSpammer) RecordRequest() {
+ e.lastRequestTime.Store(time.Now())
+}
diff --git a/turbo/engineapi/engine_server.go b/turbo/engineapi/engine_server.go
index a98f06a4c25..e79378c4355 100644
--- a/turbo/engineapi/engine_server.go
+++ b/turbo/engineapi/engine_server.go
@@ -18,7 +18,6 @@ package engineapi
import (
"context"
- "encoding/binary"
"errors"
"fmt"
"math/big"
@@ -46,6 +45,7 @@ import (
"github.com/erigontech/erigon/rpc"
"github.com/erigontech/erigon/turbo/engineapi/engine_block_downloader"
"github.com/erigontech/erigon/turbo/engineapi/engine_helpers"
+ "github.com/erigontech/erigon/turbo/engineapi/engine_logs_spammer"
"github.com/erigontech/erigon/turbo/engineapi/engine_types"
"github.com/erigontech/erigon/turbo/execution/eth1/eth1_chain_reader.go"
"github.com/erigontech/erigon/turbo/jsonrpc"
@@ -70,6 +70,8 @@ type EngineServer struct {
chainRW eth1_chain_reader.ChainReaderWriterEth1
lock sync.Mutex
logger log.Logger
+
+ engineLogSpamer *engine_logs_spammer.EngineLogsSpammer
}
const fcuTimeout = 1000 // according to mathematics: 1000 millisecods = 1 second
@@ -87,6 +89,7 @@ func NewEngineServer(logger log.Logger, config *chain.Config, executionService e
proposing: proposing,
hd: hd,
caplin: caplin,
+ engineLogSpamer: engine_logs_spammer.NewEngineLogsSpammer(logger, config),
}
}
@@ -102,6 +105,9 @@ func (e *EngineServer) Start(
txPool txpool.TxpoolClient,
mining txpool.MiningClient,
) {
+ if !e.caplin {
+ e.engineLogSpamer.Start(ctx)
+ }
base := jsonrpc.NewBaseApi(filters, stateCache, blockReader, httpConfig.WithDatadir, httpConfig.EvmCallTimeout, engineReader, httpConfig.Dirs, nil)
ethImpl := jsonrpc.NewEthAPI(base, db, eth, txPool, mining, httpConfig.Gascap, httpConfig.Feecap, httpConfig.ReturnDataLimit, httpConfig.AllowUnprotectedTxs, httpConfig.MaxGetProofRewindBlockCount, httpConfig.WebsocketSubscribeLogsChannelSize, e.logger)
@@ -160,6 +166,7 @@ func (s *EngineServer) newPayload(ctx context.Context, req *engine_types.Executi
s.logger.Crit(caplinEnabledLog)
return nil, errCaplinEnabled
}
+ s.engineLogSpamer.RecordRequest()
if len(req.LogsBloom) != types.BloomByteLength {
return nil, &rpc.InvalidParamsError{Message: fmt.Sprintf("invalid logsBloom length: %d", len(req.LogsBloom))}
@@ -458,6 +465,8 @@ func (s *EngineServer) getPayload(ctx context.Context, payloadId uint64, version
s.logger.Crit("[NewPayload] caplin is enabled")
return nil, errCaplinEnabled
}
+ s.engineLogSpamer.RecordRequest()
+
if !s.proposing {
return nil, errors.New("execution layer not running as a proposer. enable proposer by taking out the --proposer.disable flag on startup")
}
@@ -526,6 +535,8 @@ func (s *EngineServer) forkchoiceUpdated(ctx context.Context, forkchoiceState *e
s.logger.Crit("[NewPayload] caplin is enabled")
return nil, errCaplinEnabled
}
+ s.engineLogSpamer.RecordRequest()
+
status, err := s.getQuickPayloadStatusIfPossible(ctx, forkchoiceState.HeadHash, 0, libcommon.Hash{}, forkchoiceState, false)
if err != nil {
return nil, err
@@ -629,6 +640,8 @@ func (s *EngineServer) getPayloadBodiesByHash(ctx context.Context, request []lib
if len(request) > 1024 {
return nil, &engine_helpers.TooLargeRequestErr
}
+ s.engineLogSpamer.RecordRequest()
+
bodies, err := s.chainRW.GetBodiesByHashes(ctx, request)
if err != nil {
return nil, err
@@ -674,135 +687,6 @@ func (s *EngineServer) getPayloadBodiesByRange(ctx context.Context, start, count
return resp, nil
}
-// Returns the most recent version of the payload(for the payloadID) at the time of receiving the call
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_getpayloadv1
-func (e *EngineServer) GetPayloadV1(ctx context.Context, payloadId hexutility.Bytes) (*engine_types.ExecutionPayload, error) {
- if e.caplin {
- e.logger.Crit(caplinEnabledLog)
- return nil, errCaplinEnabled
- }
- decodedPayloadId := binary.BigEndian.Uint64(payloadId)
- e.logger.Info("Received GetPayloadV1", "payloadId", decodedPayloadId)
-
- response, err := e.getPayload(ctx, decodedPayloadId, clparams.BellatrixVersion)
- if err != nil {
- return nil, err
- }
-
- return response.ExecutionPayload, nil
-}
-
-// Same as [GetPayloadV1] with addition of blockValue
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadv2
-func (e *EngineServer) GetPayloadV2(ctx context.Context, payloadID hexutility.Bytes) (*engine_types.GetPayloadResponse, error) {
- decodedPayloadId := binary.BigEndian.Uint64(payloadID)
- e.logger.Info("Received GetPayloadV2", "payloadId", decodedPayloadId)
- return e.getPayload(ctx, decodedPayloadId, clparams.CapellaVersion)
-}
-
-// Same as [GetPayloadV2], with addition of blobsBundle containing valid blobs, commitments, proofs
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#engine_getpayloadv3
-func (e *EngineServer) GetPayloadV3(ctx context.Context, payloadID hexutility.Bytes) (*engine_types.GetPayloadResponse, error) {
- decodedPayloadId := binary.BigEndian.Uint64(payloadID)
- e.logger.Info("Received GetPayloadV3", "payloadId", decodedPayloadId)
- return e.getPayload(ctx, decodedPayloadId, clparams.DenebVersion)
-}
-
-// Same as [GetPayloadV3], but returning ExecutionPayloadV4 (= ExecutionPayloadV3 + requests)
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#engine_getpayloadv4
-func (e *EngineServer) GetPayloadV4(ctx context.Context, payloadID hexutility.Bytes) (*engine_types.GetPayloadResponse, error) {
- decodedPayloadId := binary.BigEndian.Uint64(payloadID)
- e.logger.Info("Received GetPayloadV4", "payloadId", decodedPayloadId)
- return e.getPayload(ctx, decodedPayloadId, clparams.ElectraVersion)
-}
-
-// Updates the forkchoice state after validating the headBlockHash
-// Additionally, builds and returns a unique identifier for an initial version of a payload
-// (asynchronously updated with transactions), if payloadAttributes is not nil and passes validation
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_forkchoiceupdatedv1
-func (e *EngineServer) ForkchoiceUpdatedV1(ctx context.Context, forkChoiceState *engine_types.ForkChoiceState, payloadAttributes *engine_types.PayloadAttributes) (*engine_types.ForkChoiceUpdatedResponse, error) {
- return e.forkchoiceUpdated(ctx, forkChoiceState, payloadAttributes, clparams.BellatrixVersion)
-}
-
-// Same as, and a replacement for, [ForkchoiceUpdatedV1], post Shanghai
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_forkchoiceupdatedv2
-func (e *EngineServer) ForkchoiceUpdatedV2(ctx context.Context, forkChoiceState *engine_types.ForkChoiceState, payloadAttributes *engine_types.PayloadAttributes) (*engine_types.ForkChoiceUpdatedResponse, error) {
- return e.forkchoiceUpdated(ctx, forkChoiceState, payloadAttributes, clparams.CapellaVersion)
-}
-
-// Successor of [ForkchoiceUpdatedV2] post Cancun, with stricter check on params
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#engine_forkchoiceupdatedv3
-func (e *EngineServer) ForkchoiceUpdatedV3(ctx context.Context, forkChoiceState *engine_types.ForkChoiceState, payloadAttributes *engine_types.PayloadAttributes) (*engine_types.ForkChoiceUpdatedResponse, error) {
- return e.forkchoiceUpdated(ctx, forkChoiceState, payloadAttributes, clparams.DenebVersion)
-}
-
-// NewPayloadV1 processes new payloads (blocks) from the beacon chain without withdrawals.
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_newpayloadv1
-func (e *EngineServer) NewPayloadV1(ctx context.Context, payload *engine_types.ExecutionPayload) (*engine_types.PayloadStatus, error) {
- return e.newPayload(ctx, payload, nil, nil, nil, clparams.BellatrixVersion)
-}
-
-// NewPayloadV2 processes new payloads (blocks) from the beacon chain with withdrawals.
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_newpayloadv2
-func (e *EngineServer) NewPayloadV2(ctx context.Context, payload *engine_types.ExecutionPayload) (*engine_types.PayloadStatus, error) {
- return e.newPayload(ctx, payload, nil, nil, nil, clparams.CapellaVersion)
-}
-
-// NewPayloadV3 processes new payloads (blocks) from the beacon chain with withdrawals & blob gas.
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#engine_newpayloadv3
-func (e *EngineServer) NewPayloadV3(ctx context.Context, payload *engine_types.ExecutionPayload,
- expectedBlobHashes []libcommon.Hash, parentBeaconBlockRoot *libcommon.Hash) (*engine_types.PayloadStatus, error) {
- return e.newPayload(ctx, payload, expectedBlobHashes, parentBeaconBlockRoot, nil, clparams.DenebVersion)
-}
-
-// NewPayloadV4 processes new payloads (blocks) from the beacon chain with withdrawals, blob gas and requests.
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#engine_newpayloadv4
-func (e *EngineServer) NewPayloadV4(ctx context.Context, payload *engine_types.ExecutionPayload,
- expectedBlobHashes []libcommon.Hash, parentBeaconBlockRoot *libcommon.Hash, executionRequests []hexutility.Bytes) (*engine_types.PayloadStatus, error) {
- // TODO(racytech): add proper version or refactor this part
- // add all version ralated checks here so the newpayload doesn't have to deal with checks
- return e.newPayload(ctx, payload, expectedBlobHashes, parentBeaconBlockRoot, executionRequests, clparams.ElectraVersion)
-}
-
-// Returns an array of execution payload bodies referenced by their block hashes
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadbodiesbyhashv1
-func (e *EngineServer) GetPayloadBodiesByHashV1(ctx context.Context, hashes []libcommon.Hash) ([]*engine_types.ExecutionPayloadBody, error) {
- return e.getPayloadBodiesByHash(ctx, hashes)
-}
-
-// Returns an ordered (as per canonical chain) array of execution payload bodies, with corresponding execution block numbers from "start", up to "count"
-// See https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadbodiesbyrangev1
-func (e *EngineServer) GetPayloadBodiesByRangeV1(ctx context.Context, start, count hexutil.Uint64) ([]*engine_types.ExecutionPayloadBody, error) {
- return e.getPayloadBodiesByRange(ctx, uint64(start), uint64(count))
-}
-
-var ourCapabilities = []string{
- "engine_forkchoiceUpdatedV1",
- "engine_forkchoiceUpdatedV2",
- "engine_forkchoiceUpdatedV3",
- "engine_newPayloadV1",
- "engine_newPayloadV2",
- "engine_newPayloadV3",
- "engine_newPayloadV4",
- "engine_getPayloadV1",
- "engine_getPayloadV2",
- "engine_getPayloadV3",
- "engine_getPayloadV4",
- "engine_getPayloadBodiesByHashV1",
- "engine_getPayloadBodiesByRangeV1",
-}
-
-func (e *EngineServer) ExchangeCapabilities(fromCl []string) []string {
- missingOurs := compareCapabilities(fromCl, ourCapabilities)
- missingCl := compareCapabilities(ourCapabilities, fromCl)
-
- if len(missingCl) > 0 || len(missingOurs) > 0 {
- e.logger.Debug("ExchangeCapabilities mismatches", "cl_unsupported", missingCl, "erigon_unsupported", missingOurs)
- }
-
- return ourCapabilities
-}
-
func compareCapabilities(from []string, to []string) []string {
result := make([]string, 0)
for _, f := range from {
@@ -827,6 +711,8 @@ func (e *EngineServer) HandleNewPayload(
block *types.Block,
versionedHashes []libcommon.Hash,
) (*engine_types.PayloadStatus, error) {
+ e.engineLogSpamer.RecordRequest()
+
header := block.Header()
headerNumber := header.Number.Uint64()
headerHash := block.Hash()
@@ -936,6 +822,8 @@ func (e *EngineServer) HandlesForkChoice(
forkChoice *engine_types.ForkChoiceState,
requestId int,
) (*engine_types.PayloadStatus, error) {
+ e.engineLogSpamer.RecordRequest()
+
headerHash := forkChoice.HeadHash
e.logger.Debug(fmt.Sprintf("[%s] Handling fork choice", logPrefix), "headerHash", headerHash)
diff --git a/turbo/engineapi/engine_types/jsonrpc.go b/turbo/engineapi/engine_types/jsonrpc.go
index 93e375cbbcc..021a4a96125 100644
--- a/turbo/engineapi/engine_types/jsonrpc.go
+++ b/turbo/engineapi/engine_types/jsonrpc.go
@@ -20,6 +20,7 @@ import (
"encoding/binary"
"encoding/json"
"errors"
+ "fmt"
"github.com/erigontech/erigon-lib/common/hexutil"
@@ -107,6 +108,17 @@ type GetPayloadResponse struct {
ShouldOverrideBuilder bool `json:"shouldOverrideBuilder"`
}
+type ClientVersionV1 struct {
+ Code string `json:"code" gencodec:"required"`
+ Name string `json:"name" gencodec:"required"`
+ Version string `json:"version" gencodec:"required"`
+ Commit [4]byte `json:"commit" gencodec:"required"`
+}
+
+func (c ClientVersionV1) String() string {
+ return fmt.Sprintf("ClientCode: %s, %s-%s-%s", c.Code, c.Name, c.Version, c.Commit)
+}
+
type StringifiedError struct{ err error }
func NewStringifiedError(err error) *StringifiedError {
diff --git a/turbo/engineapi/interface.go b/turbo/engineapi/interface.go
index d7f627cb4ce..6fb5e51b4e4 100644
--- a/turbo/engineapi/interface.go
+++ b/turbo/engineapi/interface.go
@@ -40,4 +40,5 @@ type EngineAPI interface {
GetPayloadV4(ctx context.Context, payloadID hexutility.Bytes) (*engine_types.GetPayloadResponse, error)
GetPayloadBodiesByHashV1(ctx context.Context, hashes []common.Hash) ([]*engine_types.ExecutionPayloadBody, error)
GetPayloadBodiesByRangeV1(ctx context.Context, start, count hexutil.Uint64) ([]*engine_types.ExecutionPayloadBody, error)
+ GetClientVersionV1(ctx context.Context, callerVersion *engine_types.ClientVersionV1) ([]engine_types.ClientVersionV1, error)
}
diff --git a/turbo/jsonrpc/contracts/gen.go b/turbo/jsonrpc/contracts/gen.go
index d0c8616de30..89046154b84 100644
--- a/turbo/jsonrpc/contracts/gen.go
+++ b/turbo/jsonrpc/contracts/gen.go
@@ -18,3 +18,7 @@ package contracts
//go:generate solc --allow-paths ., --abi --bin --overwrite --optimize -o build token.sol
//go:generate abigen -abi build/Token.abi -bin build/Token.bin -pkg contracts -type token -out ./gen_token.go
+
+// poly.sol
+//go:generate solc --allow-paths ., --abi --bin --overwrite --optimize -o build poly.sol
+//go:generate abigen -abi build/Poly.abi -bin build/Poly.bin -pkg contracts -type poly -out ./gen_poly.go
diff --git a/turbo/jsonrpc/contracts/gen_poly.go b/turbo/jsonrpc/contracts/gen_poly.go
index dd984a87a22..3d5a287d4da 100644
--- a/turbo/jsonrpc/contracts/gen_poly.go
+++ b/turbo/jsonrpc/contracts/gen_poly.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// PolyABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployPoly(auth *bind.TransactOpts, backend bind.ContractBackend) (libcommo
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PolyBin), backend)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(PolyBin), backend)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
@@ -232,6 +234,80 @@ func (_Poly *PolyTransactorSession) DeployAndDestruct(salt *big.Int) (types.Tran
return _Poly.Contract.DeployAndDestruct(&_Poly.TransactOpts, salt)
}
+// PolyDeployParams is an auto generated read-only Go binding of transcaction calldata params
+type PolyDeployParams struct {
+ Param_salt *big.Int
+}
+
+// Parse Deploy method from calldata of a transaction
+//
+// Solidity: function deploy(uint256 salt) returns()
+func ParsePolyDeployParams(calldata []byte) (*PolyDeployParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(PolyABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["deploy"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack deploy params data: %w", err)
+ }
+
+ var paramsResult = new(PolyDeployParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &PolyDeployParams{
+ Param_salt: out0,
+ }, nil
+}
+
+// PolyDeployAndDestructParams is an auto generated read-only Go binding of transcaction calldata params
+type PolyDeployAndDestructParams struct {
+ Param_salt *big.Int
+}
+
+// Parse DeployAndDestruct method from calldata of a transaction
+//
+// Solidity: function deployAndDestruct(uint256 salt) returns()
+func ParsePolyDeployAndDestructParams(calldata []byte) (*PolyDeployAndDestructParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(PolyABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["deployAndDestruct"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack deployAndDestruct params data: %w", err)
+ }
+
+ var paramsResult = new(PolyDeployAndDestructParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return &PolyDeployAndDestructParams{
+ Param_salt: out0,
+ }, nil
+}
+
// PolyDeployEventIterator is returned from FilterDeployEvent and is used to iterate over the raw logs and unpacked data for DeployEvent events raised by the Poly contract.
type PolyDeployEventIterator struct {
Event *PolyDeployEvent // Event containing the contract specifics and raw log
@@ -305,6 +381,10 @@ type PolyDeployEvent struct {
Raw types.Log // Blockchain specific contextual infos
}
+func (_Poly *PolyFilterer) DeployEventEventID() libcommon.Hash {
+ return libcommon.HexToHash("0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb")
+}
+
// FilterDeployEvent is a free log retrieval operation binding the contract event 0x68f6a0f063c25c6678c443b9a484086f15ba8f91f60218695d32a5251f2050eb.
//
// Solidity: event DeployEvent(address d)
@@ -362,5 +442,6 @@ func (_Poly *PolyFilterer) ParseDeployEvent(log types.Log) (*PolyDeployEvent, er
if err := _Poly.contract.UnpackLog(event, "DeployEvent", log); err != nil {
return nil, err
}
+ event.Raw = log
return event, nil
}
diff --git a/turbo/jsonrpc/contracts/gen_token.go b/turbo/jsonrpc/contracts/gen_token.go
index 124fcb5f587..e12ee0af782 100644
--- a/turbo/jsonrpc/contracts/gen_token.go
+++ b/turbo/jsonrpc/contracts/gen_token.go
@@ -1,18 +1,18 @@
-// Code generated - DO NOT EDIT.
+// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package contracts
import (
+ "fmt"
"math/big"
+ "reflect"
"strings"
- libcommon "github.com/erigontech/erigon-lib/common"
-
ethereum "github.com/erigontech/erigon"
+ libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/accounts/abi"
"github.com/erigontech/erigon/accounts/abi/bind"
- "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/event"
)
@@ -26,6 +26,8 @@ var (
_ = libcommon.Big1
_ = types.BloomLookup
_ = event.NewSubscription
+ _ = fmt.Errorf
+ _ = reflect.ValueOf
)
// TokenABI is the input ABI used to generate the binding from.
@@ -41,7 +43,7 @@ func DeployToken(auth *bind.TransactOpts, backend bind.ContractBackend, _minter
return libcommon.Address{}, nil, nil, err
}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TokenBin), backend, _minter)
+ address, tx, contract, err := bind.DeployContract(auth, parsed, libcommon.FromHex(TokenBin), backend, _minter)
if err != nil {
return libcommon.Address{}, nil, nil, err
}
@@ -324,3 +326,81 @@ func (_Token *TokenSession) Transfer(_to libcommon.Address, _value *big.Int) (ty
func (_Token *TokenTransactorSession) Transfer(_to libcommon.Address, _value *big.Int) (types.Transaction, error) {
return _Token.Contract.Transfer(&_Token.TransactOpts, _to, _value)
}
+
+// TokenMintParams is an auto generated read-only Go binding of transcaction calldata params
+type TokenMintParams struct {
+ Param__to libcommon.Address
+ Param__value *big.Int
+}
+
+// Parse Mint method from calldata of a transaction
+//
+// Solidity: function mint(address _to, uint256 _value) returns(bool)
+func ParseTokenMintParams(calldata []byte) (*TokenMintParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TokenABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["mint"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack mint params data: %w", err)
+ }
+
+ var paramsResult = new(TokenMintParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(libcommon.Address)).(*libcommon.Address)
+ out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+
+ return &TokenMintParams{
+ Param__to: out0, Param__value: out1,
+ }, nil
+}
+
+// TokenTransferParams is an auto generated read-only Go binding of transcaction calldata params
+type TokenTransferParams struct {
+ Param__to libcommon.Address
+ Param__value *big.Int
+}
+
+// Parse Transfer method from calldata of a transaction
+//
+// Solidity: function transfer(address _to, uint256 _value) returns(bool)
+func ParseTokenTransferParams(calldata []byte) (*TokenTransferParams, error) {
+ if len(calldata) <= 4 {
+ return nil, fmt.Errorf("invalid calldata input")
+ }
+
+ _abi, err := abi.JSON(strings.NewReader(TokenABI))
+ if err != nil {
+ return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
+ }
+
+ out, err := _abi.Methods["transfer"].Inputs.Unpack(calldata[4:])
+ if err != nil {
+ return nil, fmt.Errorf("failed to unpack transfer params data: %w", err)
+ }
+
+ var paramsResult = new(TokenTransferParams)
+ value := reflect.ValueOf(paramsResult).Elem()
+
+ if value.NumField() != len(out) {
+ return nil, fmt.Errorf("failed to match calldata with param field number")
+ }
+
+ out0 := *abi.ConvertType(out[0], new(libcommon.Address)).(*libcommon.Address)
+ out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+
+ return &TokenTransferParams{
+ Param__to: out0, Param__value: out1,
+ }, nil
+}
diff --git a/turbo/jsonrpc/eth_api.go b/turbo/jsonrpc/eth_api.go
index 6d797737ef0..8190588c2aa 100644
--- a/turbo/jsonrpc/eth_api.go
+++ b/turbo/jsonrpc/eth_api.go
@@ -192,7 +192,7 @@ func (api *BaseAPI) genesis(ctx context.Context, tx kv.Tx) (*types.Block, error)
return genesis, err
}
-func (api *BaseAPI) txnLookup(ctx context.Context, tx kv.Tx, txnHash common.Hash) (uint64, bool, error) {
+func (api *BaseAPI) txnLookup(ctx context.Context, tx kv.Tx, txnHash common.Hash) (blockNum uint64, txNum uint64, ok bool, err error) {
return api._txnReader.TxnLookup(ctx, tx, txnHash)
}
diff --git a/turbo/jsonrpc/eth_block.go b/turbo/jsonrpc/eth_block.go
index 8133a2e9180..187e0c95282 100644
--- a/turbo/jsonrpc/eth_block.go
+++ b/turbo/jsonrpc/eth_block.go
@@ -67,7 +67,7 @@ func (api *APIImpl) CallBundle(ctx context.Context, txHashes []common.Hash, stat
var txs types.Transactions
for _, txHash := range txHashes {
- blockNum, ok, err := api.txnLookup(ctx, tx, txHash)
+ blockNum, _, ok, err := api.txnLookup(ctx, tx, txHash)
if err != nil {
return nil, err
}
diff --git a/turbo/jsonrpc/eth_call.go b/turbo/jsonrpc/eth_call.go
index dd5d90c5c07..eb4c18780be 100644
--- a/turbo/jsonrpc/eth_call.go
+++ b/turbo/jsonrpc/eth_call.go
@@ -17,14 +17,22 @@
package jsonrpc
import (
+ "bytes"
"context"
"errors"
"fmt"
"math/big"
+ "github.com/erigontech/erigon-lib/kv/dbutils"
+ "github.com/erigontech/erigon-lib/trie"
+
+ "github.com/erigontech/erigon-lib/commitment"
+ libstate "github.com/erigontech/erigon-lib/state"
"github.com/holiman/uint256"
"google.golang.org/grpc"
+ "github.com/erigontech/erigon-lib/kv/membatchwithdb"
+
libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/hexutil"
"github.com/erigontech/erigon-lib/common/hexutility"
@@ -35,11 +43,13 @@ import (
"github.com/erigontech/erigon-lib/kv/rawdbv3"
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon-lib/types/accounts"
+ "github.com/erigontech/erigon/consensus"
"github.com/erigontech/erigon/core"
"github.com/erigontech/erigon/core/state"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/core/vm"
"github.com/erigontech/erigon/core/vm/evmtypes"
+ "github.com/erigontech/erigon/eth/stagedsync"
"github.com/erigontech/erigon/eth/tracers/logger"
"github.com/erigontech/erigon/params"
"github.com/erigontech/erigon/rpc"
@@ -205,7 +215,10 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
return 0, errors.New("can't get the current state")
}
- balance := state.GetBalance(*args.From) // from can't be nil
+ balance, err := state.GetBalance(*args.From) // from can't be nil
+ if err != nil {
+ return 0, err
+ }
available := balance.ToBig()
if args.Value != nil {
if args.Value.ToInt().Cmp(available) >= 0 {
@@ -417,6 +430,217 @@ func (api *APIImpl) GetProof(ctx context.Context, address libcommon.Address, sto
*/
}
+func (api *APIImpl) GetWitness(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) {
+ return api.getWitness(ctx, api.db, blockNrOrHash, 0, true, api.MaxGetProofRewindBlockCount, api.logger)
+}
+
+func (api *APIImpl) GetTxWitness(ctx context.Context, blockNr rpc.BlockNumberOrHash, txIndex hexutil.Uint) (hexutility.Bytes, error) {
+ return api.getWitness(ctx, api.db, blockNr, txIndex, false, api.MaxGetProofRewindBlockCount, api.logger)
+}
+
+func verifyExecResult(execResult *core.EphemeralExecResult, block *types.Block) error {
+ actualTxRoot := execResult.TxRoot.Bytes()
+ expectedTxRoot := block.TxHash().Bytes()
+ if !bytes.Equal(actualTxRoot, expectedTxRoot) {
+ return fmt.Errorf("mismatch in block TxRoot actual(%x) != expected(%x)", actualTxRoot, expectedTxRoot)
+ }
+
+ actualGasUsed := uint64(execResult.GasUsed)
+ expectedGasUsed := block.GasUsed()
+ if actualGasUsed != expectedGasUsed {
+ return fmt.Errorf("mismatch in block gas used actual(%x) != expected(%x)", actualGasUsed, expectedGasUsed)
+ }
+
+ actualReceiptsHash := execResult.ReceiptRoot.Bytes()
+ expectedReceiptsHash := block.ReceiptHash().Bytes()
+ if !bytes.Equal(actualReceiptsHash, expectedReceiptsHash) {
+ return fmt.Errorf("mismatch in receipts hash actual(%x) != expected(%x)", actualReceiptsHash, expectedReceiptsHash)
+ }
+
+ // check the state root
+ resultingStateRoot := execResult.StateRoot.Bytes()
+ expectedBlockStateRoot := block.Root().Bytes()
+ if !bytes.Equal(resultingStateRoot, expectedBlockStateRoot) {
+ return fmt.Errorf("resulting state root after execution doesn't match state root in block actual(%x)!=expected(%x)", resultingStateRoot, expectedBlockStateRoot)
+ }
+ return nil
+}
+
+func (api *BaseAPI) getWitness(ctx context.Context, db kv.RoDB, blockNrOrHash rpc.BlockNumberOrHash, txIndex hexutil.Uint, fullBlock bool, maxGetProofRewindBlockCount int, logger log.Logger) (hexutility.Bytes, error) {
+ roTx, err := db.BeginRo(ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer roTx.Rollback()
+
+ blockNr, hash, _, err := rpchelper.GetCanonicalBlockNumber(ctx, blockNrOrHash, roTx, api._blockReader, api.filters) // DoCall cannot be executed on non-canonical blocks
+ if err != nil {
+ return nil, err
+ }
+
+ // Witness for genesis block is empty
+ if blockNr == 0 {
+ w := trie.NewWitness(make([]trie.WitnessOperator, 0))
+
+ var buf bytes.Buffer
+ _, err = w.WriteInto(&buf)
+ if err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+ }
+
+ block, err := api.blockWithSenders(ctx, roTx, hash, blockNr)
+ if err != nil {
+ return nil, err
+ }
+ if block == nil {
+ return nil, nil
+ }
+
+ if !fullBlock && int(txIndex) >= len(block.Transactions()) {
+ return nil, fmt.Errorf("transaction index out of bounds: %d", txIndex)
+ }
+
+ latestBlock, err := rpchelper.GetLatestBlockNumber(roTx)
+ if err != nil {
+ return nil, err
+ }
+
+ if latestBlock < blockNr {
+ // shouldn't happen, but check anyway
+ return nil, fmt.Errorf("block number is in the future latest=%d requested=%d", latestBlock, blockNr)
+ }
+
+ // Compute the witness if it's for a tx or it's not present in db
+ prevHeader, err := api._blockReader.HeaderByNumber(ctx, roTx, blockNr-1)
+ if err != nil {
+ return nil, err
+ }
+
+ regenerateHash := false
+ if latestBlock-blockNr > uint64(maxGetProofRewindBlockCount) {
+ regenerateHash = true
+ }
+
+ engine, ok := api.engine().(consensus.Engine)
+ if !ok {
+ return nil, errors.New("engine is not consensus.Engine")
+ }
+
+ roTx2, err := db.BeginRo(ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer roTx2.Rollback()
+ txBatch2 := membatchwithdb.NewMemoryBatch(roTx2, "", logger)
+ defer txBatch2.Rollback()
+
+ // Prepare witness config
+ chainConfig, err := api.chainConfig(ctx, roTx2)
+ if err != nil {
+ return nil, fmt.Errorf("error loading chain config: %v", err)
+ }
+
+ // Unwind to blockNr
+ cfg := stagedsync.StageWitnessCfg(true, 0, chainConfig, engine, api._blockReader, api.dirs)
+ err = stagedsync.RewindStagesForWitness(txBatch2, blockNr, latestBlock, &cfg, regenerateHash, ctx, logger)
+ if err != nil {
+ return nil, err
+ }
+
+ store, err := stagedsync.PrepareForWitness(txBatch2, block, prevHeader.Root, &cfg, ctx, logger)
+ if err != nil {
+ return nil, err
+ }
+
+ domains, err := libstate.NewSharedDomains(txBatch2, log.New())
+ if err != nil {
+ return nil, err
+ }
+ sdCtx := libstate.NewSharedDomainsCommitmentContext(domains, commitment.ModeUpdate, commitment.VariantHexPatriciaTrie)
+ patricieTrie := sdCtx.Trie()
+ hph, ok := patricieTrie.(*commitment.HexPatriciaHashed)
+ if !ok {
+ return nil, errors.New("casting to HexPatriciaTrieHashed failed")
+ }
+
+ // execute block #blockNr ephemerally. This will use TrieStateWriter to record touches of accounts and storage keys.
+ _, err = core.ExecuteBlockEphemerally(chainConfig, &vm.Config{}, store.GetHashFn, engine, block, store.Tds, store.TrieStateWriter, store.ChainReader, nil, logger)
+ if err != nil {
+ return nil, err
+ }
+
+ // gather touched keys from ephemeral block execution
+ touchedPlainKeys, touchedHashedKeys := store.Tds.GetTouchedPlainKeys()
+ codeReads := store.Tds.BuildCodeTouches()
+
+ // define these keys as "updates", but we are not really updating anything, we just want to load them into the grid,
+ // so this is just to satisfy the current hex patricia trie api.
+ updates := commitment.NewUpdates(commitment.ModeDirect, sdCtx.TempDir(), hph.HashAndNibblizeKey)
+ for _, key := range touchedPlainKeys {
+ updates.TouchPlainKey(string(key), nil, updates.TouchAccount)
+ }
+
+ hph.SetTrace(false) // disable tracing to avoid mixing with trace from witness computation
+ // generate the block witness, this works by loading the merkle paths to the touched keys (they are loaded from the state at block #blockNr-1)
+ witnessTrie, witnessRootHash, err := hph.GenerateWitness(ctx, updates, codeReads, prevHeader.Root[:], "computeWitness")
+ if err != nil {
+ return nil, err
+ }
+
+ //
+ if !bytes.Equal(witnessRootHash, prevHeader.Root[:]) {
+ return nil, fmt.Errorf("witness root hash mismatch actual(%x)!=expected(%x)", witnessRootHash, prevHeader.Root[:])
+ }
+
+ // retain list is need for the serialization of the trie.Trie into a witness
+ retainListBuilder := trie.NewRetainListBuilder()
+ for _, key := range touchedHashedKeys {
+ if len(key) == 32 {
+ retainListBuilder.AddTouch(key)
+ } else {
+ addr, _, hash := dbutils.ParseCompositeStorageKey(key)
+ storageTouch := dbutils.GenerateCompositeTrieKey(addr, hash)
+ retainListBuilder.AddStorageTouch(storageTouch)
+ }
+ }
+
+ for _, codeWithHash := range codeReads {
+ retainListBuilder.ReadCode(codeWithHash.CodeHash, codeWithHash.Code)
+ }
+
+ retainList := retainListBuilder.Build(false)
+
+ // serialize witness trie
+ witness, err := witnessTrie.ExtractWitness(true, retainList)
+ if err != nil {
+ return nil, err
+ }
+
+ var witnessBuffer bytes.Buffer
+ _, err = witness.WriteInto(&witnessBuffer)
+ if err != nil {
+ return nil, err
+ }
+
+ // this is a verification step: we execute block #blockNr statelessly using the witness, and we expect to get the same state root as in the header
+ // otherwise something went wrong
+ store.Tds.SetTrie(witnessTrie)
+ newStateRoot, err := stagedsync.ExecuteBlockStatelessly(block, prevHeader, store.ChainReader, store.Tds, &cfg, &witnessBuffer, store.GetHashFn, logger)
+ if err != nil {
+ return nil, err
+ }
+ if !bytes.Equal(newStateRoot.Bytes(), block.Root().Bytes()) {
+ fmt.Printf("state root mismatch after stateless execution actual(%x) != expected(%x)\n", newStateRoot.Bytes(), block.Root().Bytes())
+ }
+ witnessBufBytes := witnessBuffer.Bytes()
+ witnessBufBytesCopy := make([]byte, len(witnessBufBytes))
+ copy(witnessBufBytesCopy, witnessBufBytes)
+ return witnessBufBytesCopy, nil
+}
+
func (api *APIImpl) tryBlockFromLru(hash libcommon.Hash) *types.Block {
var block *types.Block
if api.blocksLRU != nil {
diff --git a/turbo/jsonrpc/eth_call_test.go b/turbo/jsonrpc/eth_call_test.go
index 5086f52a343..ac0e1a7e9fb 100644
--- a/turbo/jsonrpc/eth_call_test.go
+++ b/turbo/jsonrpc/eth_call_test.go
@@ -553,13 +553,17 @@ func chainWithDeployedContract(t *testing.T) (*mock.MockSentry, libcommon.Addres
assert.NoError(t, err)
st := state.New(stateReader)
assert.NoError(t, err)
- assert.False(t, st.Exist(contractAddr), "Contract should not exist at block #1")
+ exist, err := st.Exist(contractAddr)
+ assert.NoError(t, err)
+ assert.False(t, exist, "Contract should not exist at block #1")
stateReader, err = rpchelper.CreateHistoryStateReader(tx, rawdbv3.TxNums, 2, 0, "")
assert.NoError(t, err)
st = state.New(stateReader)
assert.NoError(t, err)
- assert.True(t, st.Exist(contractAddr), "Contract should exist at block #2")
+ exist, err = st.Exist(contractAddr)
+ assert.NoError(t, err)
+ assert.True(t, exist, "Contract should exist at block #2")
return m, bankAddress, contractAddr
}
diff --git a/turbo/jsonrpc/eth_receipts.go b/turbo/jsonrpc/eth_receipts.go
index 1d83d559ace..31a7522ca4f 100644
--- a/turbo/jsonrpc/eth_receipts.go
+++ b/turbo/jsonrpc/eth_receipts.go
@@ -51,8 +51,8 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.TemporalTx, block *ty
return api.receiptsGenerator.GetReceipts(ctx, chainConfig, tx, block)
}
-func (api *BaseAPI) getReceipt(ctx context.Context, cc *chain.Config, tx kv.TemporalTx, block *types.Block, index int, optimize bool) (*types.Receipt, error) {
- return api.receiptsGenerator.GetReceipt(ctx, cc, tx, block, index, optimize)
+func (api *BaseAPI) getReceipt(ctx context.Context, cc *chain.Config, tx kv.TemporalTx, block *types.Block, index int, txNum uint64) (*types.Receipt, error) {
+ return api.receiptsGenerator.GetReceipt(ctx, cc, tx, block, index, txNum)
}
func (api *BaseAPI) getCachedReceipts(ctx context.Context, hash common.Hash) (types.Receipts, bool) {
@@ -407,18 +407,22 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, txnHash common.Ha
}
defer tx.Rollback()
- var blockNum uint64
+ var blockNum, txNum uint64
var ok bool
- blockNum, ok, err = api.txnLookup(ctx, tx, txnHash)
+ chainConfig, err := api.chainConfig(ctx, tx)
if err != nil {
return nil, err
}
- chainConfig, err := api.chainConfig(ctx, tx)
+ blockNum, txNum, ok, err = api.txnLookup(ctx, tx, txnHash)
if err != nil {
return nil, err
}
+ if !ok && chainConfig.Bor == nil {
+ return nil, nil
+ }
+
// Private API returns 0 if transaction is not found.
if blockNum == 0 && chainConfig.Bor != nil {
if api.useBridgeReader {
@@ -476,13 +480,12 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, txnHash common.Ha
return ethutils.MarshalReceipt(borReceipt, bortypes.NewBorTransaction(), chainConfig, block.HeaderNoCopy(), txnHash, false), nil
}
- receipt, err := api.getReceipt(ctx, chainConfig, tx, block, int(txnIndex), false)
+ receipt, err := api.getReceipt(ctx, chainConfig, tx.(kv.TemporalTx), block, int(txnIndex), txNum)
if err != nil {
return nil, fmt.Errorf("getReceipt error: %w", err)
}
return ethutils.MarshalReceipt(receipt, block.Transactions()[txnIndex], chainConfig, block.HeaderNoCopy(), txnHash, true), nil
-
}
// GetBlockReceipts - receipts for individual block
diff --git a/turbo/jsonrpc/eth_txs.go b/turbo/jsonrpc/eth_txs.go
index 38801c99d88..2232c9e5f29 100644
--- a/turbo/jsonrpc/eth_txs.go
+++ b/turbo/jsonrpc/eth_txs.go
@@ -49,7 +49,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Has
}
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByHash
- blockNum, ok, err := api.txnLookup(ctx, tx, txnHash)
+ blockNum, _, ok, err := api.txnLookup(ctx, tx, txnHash)
if err != nil {
return nil, err
}
@@ -139,7 +139,7 @@ func (api *APIImpl) GetRawTransactionByHash(ctx context.Context, hash common.Has
defer tx.Rollback()
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByHash
- blockNum, ok, err := api.txnLookup(ctx, tx, hash)
+ blockNum, _, ok, err := api.txnLookup(ctx, tx, hash)
if err != nil {
return nil, err
}
diff --git a/turbo/jsonrpc/otterscan_api.go b/turbo/jsonrpc/otterscan_api.go
index 358aaef7126..161a8d1388e 100644
--- a/turbo/jsonrpc/otterscan_api.go
+++ b/turbo/jsonrpc/otterscan_api.go
@@ -90,7 +90,7 @@ func (api *OtterscanAPIImpl) GetApiLevel() uint8 {
// TODO: dedup from eth_txs.go#GetTransactionByHash
func (api *OtterscanAPIImpl) getTransactionByHash(ctx context.Context, tx kv.Tx, hash common.Hash) (types.Transaction, *types.Block, common.Hash, uint64, uint64, error) {
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByHash
- blockNum, ok, err := api.txnLookup(ctx, tx, hash)
+ blockNum, _, ok, err := api.txnLookup(ctx, tx, hash)
if err != nil {
return nil, nil, common.Hash{}, 0, 0, err
}
diff --git a/turbo/jsonrpc/otterscan_search_v3.go b/turbo/jsonrpc/otterscan_search_v3.go
index 1bdc05874cd..dbc34b5a18a 100644
--- a/turbo/jsonrpc/otterscan_search_v3.go
+++ b/turbo/jsonrpc/otterscan_search_v3.go
@@ -53,7 +53,7 @@ func (api *OtterscanAPIImpl) buildSearchResults(ctx context.Context, tx kv.Tempo
reachedPageSize := false
hasMore := false
for txNumsIter.HasNext() {
- _, blockNum, txIndex, isFinalTxn, blockNumChanged, err := txNumsIter.Next()
+ txNum, blockNum, txIndex, isFinalTxn, blockNumChanged, err := txNumsIter.Next()
if err != nil {
return nil, nil, false, err
}
@@ -96,7 +96,7 @@ func (api *OtterscanAPIImpl) buildSearchResults(ctx context.Context, tx kv.Tempo
rpcTx := NewRPCTransaction(txn, block.Hash(), blockNum, uint64(txIndex), block.BaseFee())
txs = append(txs, rpcTx)
- receipt, err := api.receiptsGenerator.GetReceipt(ctx, chainConfig, tx, block, txIndex, false)
+ receipt, err := api.receiptsGenerator.GetReceipt(ctx, chainConfig, tx, block, txIndex, txNum+1)
if err != nil {
return nil, nil, false, err
}
diff --git a/turbo/jsonrpc/overlay_api.go b/turbo/jsonrpc/overlay_api.go
index 80c19d75c54..0072579da9b 100644
--- a/turbo/jsonrpc/overlay_api.go
+++ b/turbo/jsonrpc/overlay_api.go
@@ -115,7 +115,7 @@ func (api *OverlayAPIImpl) CallConstructor(ctx context.Context, address common.A
return nil, err
}
- blockNum, ok, err := api.txnLookup(ctx, tx, creationData.Tx)
+ blockNum, _, ok, err := api.txnLookup(ctx, tx, creationData.Tx)
if err != nil {
return nil, err
}
@@ -237,7 +237,10 @@ func (api *OverlayAPIImpl) CallConstructor(ctx context.Context, address common.A
if err != nil {
return nil, err
}
- code := evm.IntraBlockState().GetCode(address)
+ code, err := evm.IntraBlockState().GetCode(address)
+ if err != nil {
+ return nil, err
+ }
if len(code) > 0 {
c := hexutility.Bytes(code)
resultCode.Code = &c
@@ -506,7 +509,16 @@ func (api *OverlayAPIImpl) replayBlock(ctx context.Context, blockNum uint64, sta
if !contractCreation {
// bump the nonce of the sender
sender := vm.AccountRef(msg.From())
- statedb.SetNonce(msg.From(), statedb.GetNonce(sender.Address())+1)
+ nonce, err := statedb.GetNonce(sender.Address())
+ if err != nil {
+ log.Error(err.Error())
+ return nil, err
+ }
+ err = statedb.SetNonce(msg.From(), nonce+1)
+ if err != nil {
+ log.Error(err.Error())
+ return nil, err
+ }
continue
}
}
diff --git a/turbo/jsonrpc/overlay_create_tracer.go b/turbo/jsonrpc/overlay_create_tracer.go
index 29be53228a8..c80641a5465 100644
--- a/turbo/jsonrpc/overlay_create_tracer.go
+++ b/turbo/jsonrpc/overlay_create_tracer.go
@@ -55,7 +55,11 @@ func (ct *OverlayCreateTracer) CaptureEnter(typ vm.OpCode, from libcommon.Addres
if err != nil {
ct.err = err
} else {
- ct.resultCode = ct.evm.IntraBlockState().GetCode(ct.contractAddress)
+ if result, err := ct.evm.IntraBlockState().GetCode(ct.contractAddress); err != nil {
+ ct.resultCode = result
+ } else {
+ ct.err = err
+ }
}
}
}
diff --git a/turbo/jsonrpc/receipts/receipts_generator.go b/turbo/jsonrpc/receipts/receipts_generator.go
index f882587c704..4dc0dd19446 100644
--- a/turbo/jsonrpc/receipts/receipts_generator.go
+++ b/turbo/jsonrpc/receipts/receipts_generator.go
@@ -12,6 +12,7 @@ import (
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/consensus"
"github.com/erigontech/erigon/core"
+ "github.com/erigontech/erigon/core/rawdb/rawtemporaldb"
"github.com/erigontech/erigon/core/state"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/core/vm"
@@ -106,38 +107,34 @@ func (g *Generator) addToCache(header *types.Header, receipts types.Receipts) {
g.receiptsCache.Add(header.Hash(), receipts.Copy()) // .Copy() helps pprof to attribute memory to cache - instead of evm (where it was allocated).
}
-func (g *Generator) GetReceipt(ctx context.Context, cfg *chain.Config, tx kv.TemporalTx, block *types.Block, index int, optimize bool) (*types.Receipt, error) {
+func (g *Generator) GetReceipt(ctx context.Context, cfg *chain.Config, tx kv.TemporalTx, block *types.Block, index int, txNum uint64) (*types.Receipt, error) {
if receipts, ok := g.receiptsCache.Get(block.Hash()); ok && len(receipts) > index {
return receipts[index], nil
}
-
var receipt *types.Receipt
- if optimize {
- genEnv, err := g.PrepareEnv(ctx, block, cfg, tx, index)
- if err != nil {
- return nil, err
- }
- receipt, _, err = core.ApplyTransaction(cfg, core.GetHashFn(genEnv.header, genEnv.getHeader), g.engine, nil, genEnv.gp, genEnv.ibs, genEnv.noopWriter, genEnv.header, block.Transactions()[index], genEnv.usedGas, genEnv.usedBlobGas, vm.Config{})
- if err != nil {
- return nil, fmt.Errorf("ReceiptGen.GetReceipt: bn=%d, txnIdx=%d, %w", block.NumberU64(), index, err)
- }
- receipt.BlockHash = block.Hash()
- } else {
- genEnv, err := g.PrepareEnv(ctx, block, cfg, tx, 0)
- if err != nil {
- return nil, err
- }
- for i, txn := range block.Transactions() {
- genEnv.ibs.SetTxContext(i)
- receipt, _, err = core.ApplyTransaction(cfg, core.GetHashFn(genEnv.header, genEnv.getHeader), g.engine, nil, genEnv.gp, genEnv.ibs, genEnv.noopWriter, genEnv.header, txn, genEnv.usedGas, genEnv.usedBlobGas, vm.Config{})
- if err != nil {
- return nil, fmt.Errorf("ReceiptGen.GetReceipt: bn=%d, txnIdx=%d, %w", block.NumberU64(), i, err)
- }
- receipt.BlockHash = block.Hash()
- if i == index {
- break
- }
- }
+ genEnv, err := g.PrepareEnv(ctx, block, cfg, tx, index)
+ if err != nil {
+ return nil, err
+ }
+
+ cumGasUsed, _, firstLogIndex, err := rawtemporaldb.ReceiptAsOf(tx, txNum)
+ if err != nil {
+ return nil, err
+ }
+
+ receipt, _, err = core.ApplyTransaction(cfg, core.GetHashFn(genEnv.header, genEnv.getHeader), g.engine, nil, genEnv.gp, genEnv.ibs, genEnv.noopWriter, genEnv.header, block.Transactions()[index], genEnv.usedGas, genEnv.usedBlobGas, vm.Config{})
+ if err != nil {
+ return nil, fmt.Errorf("ReceiptGen.GetReceipt: bn=%d, txnIdx=%d, %w", block.NumberU64(), index, err)
+ }
+
+ receipt.BlockHash = block.Hash()
+
+ receipt.CumulativeGasUsed = cumGasUsed
+ receipt.TransactionIndex = uint(index)
+
+ for i := range receipt.Logs {
+ receipt.Logs[i].TxIndex = uint(index)
+ receipt.Logs[i].Index = uint(firstLogIndex + uint32(i))
}
return receipt, nil
diff --git a/turbo/jsonrpc/trace_adhoc.go b/turbo/jsonrpc/trace_adhoc.go
index b056b3ee197..cd52559d15a 100644
--- a/turbo/jsonrpc/trace_adhoc.go
+++ b/turbo/jsonrpc/trace_adhoc.go
@@ -662,16 +662,30 @@ func (sd *StateDiff) CreateContract(address libcommon.Address) error {
}
// CompareStates uses the addresses accumulated in the sdMap and compares balances, nonces, and codes of the accounts, and fills the rest of the sdMap
-func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) {
+func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) error {
var toRemove []libcommon.Address
for addr, accountDiff := range sd.sdMap {
- initialExist := initialIbs.Exist(addr)
- exist := ibs.Exist(addr)
+ initialExist, err := initialIbs.Exist(addr)
+ if err != nil {
+ return err
+ }
+ exist, err := ibs.Exist(addr)
+ if err != nil {
+ return err
+ }
if initialExist {
if exist {
var allEqual = len(accountDiff.Storage) == 0
- fromBalance := initialIbs.GetBalance(addr).ToBig()
- toBalance := ibs.GetBalance(addr).ToBig()
+ ifromBalance, err := initialIbs.GetBalance(addr)
+ if err != nil {
+ return err
+ }
+ fromBalance := ifromBalance.ToBig()
+ itoBalance, err := ibs.GetBalance(addr)
+ if err != nil {
+ return err
+ }
+ toBalance := itoBalance.ToBig()
if fromBalance.Cmp(toBalance) == 0 {
accountDiff.Balance = "="
} else {
@@ -680,8 +694,14 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) {
accountDiff.Balance = m
allEqual = false
}
- fromCode := initialIbs.GetCode(addr)
- toCode := ibs.GetCode(addr)
+ fromCode, err := initialIbs.GetCode(addr)
+ if err != nil {
+ return err
+ }
+ toCode, err := ibs.GetCode(addr)
+ if err != nil {
+ return err
+ }
if bytes.Equal(fromCode, toCode) {
accountDiff.Code = "="
} else {
@@ -690,8 +710,14 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) {
accountDiff.Code = m
allEqual = false
}
- fromNonce := initialIbs.GetNonce(addr)
- toNonce := ibs.GetNonce(addr)
+ fromNonce, err := initialIbs.GetNonce(addr)
+ if err != nil {
+ return err
+ }
+ toNonce, err := ibs.GetNonce(addr)
+ if err != nil {
+ return err
+ }
if fromNonce == toNonce {
accountDiff.Nonce = "="
} else {
@@ -705,35 +731,59 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) {
}
} else {
{
+ balance, err := initialIbs.GetBalance(addr)
+ if err != nil {
+ return err
+ }
m := make(map[string]*hexutil.Big)
- m["-"] = (*hexutil.Big)(initialIbs.GetBalance(addr).ToBig())
+ m["-"] = (*hexutil.Big)(balance.ToBig())
accountDiff.Balance = m
}
{
+ code, err := initialIbs.GetCode(addr)
+ if err != nil {
+ return err
+ }
m := make(map[string]hexutility.Bytes)
- m["-"] = initialIbs.GetCode(addr)
+ m["-"] = code
accountDiff.Code = m
}
{
+ nonce, err := initialIbs.GetNonce(addr)
+ if err != nil {
+ return err
+ }
m := make(map[string]hexutil.Uint64)
- m["-"] = hexutil.Uint64(initialIbs.GetNonce(addr))
+ m["-"] = hexutil.Uint64(nonce)
accountDiff.Nonce = m
}
}
} else if exist {
{
+ balance, err := ibs.GetBalance(addr)
+ if err != nil {
+ return err
+ }
m := make(map[string]*hexutil.Big)
- m["+"] = (*hexutil.Big)(ibs.GetBalance(addr).ToBig())
+ m["+"] = (*hexutil.Big)(balance.ToBig())
accountDiff.Balance = m
}
{
+ code, err := ibs.GetCode(addr)
+ if err != nil {
+ return err
+ }
m := make(map[string]hexutility.Bytes)
- m["+"] = ibs.GetCode(addr)
+ m["+"] = code
accountDiff.Code = m
}
{
+ nonce, err := ibs.GetNonce(addr)
+ if err != nil {
+ return err
+ }
m := make(map[string]hexutil.Uint64)
- m["+"] = hexutil.Uint64(ibs.GetNonce(addr))
+ m["+"] = hexutil.Uint64(nonce)
accountDiff.Nonce = m
}
// Transform storage
@@ -749,6 +799,7 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) {
for _, addr := range toRemove {
delete(sd.sdMap, addr)
}
+ return nil
}
func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool, traceConfig *config.TraceConfig) (*TraceCallResult, error) {
@@ -766,7 +817,7 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon
}
var isBorStateSyncTxn bool
- blockNum, ok, err := api.txnLookup(ctx, tx, txHash)
+ blockNum, _, ok, err := api.txnLookup(ctx, tx, txHash)
if err != nil {
return nil, err
}
diff --git a/turbo/jsonrpc/trace_filtering.go b/turbo/jsonrpc/trace_filtering.go
index 22935754dfa..1c0b410e1c3 100644
--- a/turbo/jsonrpc/trace_filtering.go
+++ b/turbo/jsonrpc/trace_filtering.go
@@ -67,7 +67,7 @@ func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash, ga
}
var isBorStateSyncTxn bool
- blockNumber, ok, err := api.txnLookup(ctx, tx, txHash)
+ blockNumber, _, ok, err := api.txnLookup(ctx, tx, txHash)
if err != nil {
return nil, err
}
@@ -780,7 +780,7 @@ func (api *TraceAPIImpl) callManyTransactions(
engine := api.engine()
consensusHeaderReader := consensuschain.NewReader(cfg, dbtx, nil, nil)
logger := log.New("trace_filtering")
- err = core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, block.HeaderNoCopy(), cfg, ibs, logger, nil)
+ err = core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, block.HeaderNoCopy(), cfg, ibs, nil, logger, nil)
if err != nil {
return nil, nil, err
}
diff --git a/turbo/jsonrpc/tracing.go b/turbo/jsonrpc/tracing.go
index f6cd1f355c0..b5735979e09 100644
--- a/turbo/jsonrpc/tracing.go
+++ b/turbo/jsonrpc/tracing.go
@@ -252,7 +252,7 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo
}
// Retrieve the transaction and assemble its EVM context
var isBorStateSyncTxn bool
- blockNum, ok, err := api.txnLookup(ctx, tx, hash)
+ blockNum, _, ok, err := api.txnLookup(ctx, tx, hash)
if err != nil {
stream.WriteNil()
return err
diff --git a/turbo/services/interfaces.go b/turbo/services/interfaces.go
index dd26a7cfd64..ceee3c57569 100644
--- a/turbo/services/interfaces.go
+++ b/turbo/services/interfaces.go
@@ -96,7 +96,7 @@ type BodyReader interface {
}
type TxnReader interface {
- TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (uint64, bool, error)
+ TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (blockNum uint64, txNum uint64, ok bool, err error)
TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, i int) (txn types.Transaction, err error)
RawTransactions(ctx context.Context, tx kv.Getter, fromBlock, toBlock uint64) (txs [][]byte, err error)
FirstTxnNumNotInSnapshots() uint64
diff --git a/turbo/snapshotsync/freezeblocks/block_reader.go b/turbo/snapshotsync/freezeblocks/block_reader.go
index ef87b25f6fb..0ab0faac892 100644
--- a/turbo/snapshotsync/freezeblocks/block_reader.go
+++ b/turbo/snapshotsync/freezeblocks/block_reader.go
@@ -164,15 +164,15 @@ func NewRemoteBlockReader(client remote.ETHBACKENDClient) *RemoteBlockReader {
return &RemoteBlockReader{client}
}
-func (r *RemoteBlockReader) TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (uint64, bool, error) {
+func (r *RemoteBlockReader) TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (uint64, uint64, bool, error) {
reply, err := r.client.TxnLookup(ctx, &remote.TxnLookupRequest{TxnHash: gointerfaces.ConvertHashToH256(txnHash)})
if err != nil {
- return 0, false, err
+ return 0, 0, false, err
}
if reply == nil {
- return 0, false, nil
+ return 0, 0, false, nil
}
- return reply.BlockNumber, true, nil
+ return reply.BlockNumber, reply.TxNumber, true, nil
}
func (r *RemoteBlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, i int) (txn types.Transaction, err error) {
@@ -1082,7 +1082,7 @@ func (r *BlockReader) txnByID(txnID uint64, sn *snapshotsync.VisibleSegment, buf
return
}
-func (r *BlockReader) txnByHash(txnHash common.Hash, segments []*snapshotsync.VisibleSegment, buf []byte) (types.Transaction, uint64, bool, error) {
+func (r *BlockReader) txnByHash(txnHash common.Hash, segments []*snapshotsync.VisibleSegment, buf []byte) (types.Transaction, uint64, uint64, bool, error) {
for i := len(segments) - 1; i >= 0; i-- {
sn := segments[i]
@@ -1094,11 +1094,11 @@ func (r *BlockReader) txnByHash(txnHash common.Hash, segments []*snapshotsync.Vi
}
reader := recsplit.NewIndexReader(idxTxnHash)
- txnId, ok := reader.Lookup(txnHash[:])
+ txNumInFile, ok := reader.Lookup(txnHash[:])
if !ok {
continue
}
- offset := idxTxnHash.OrdinalLookup(txnId)
+ offset := idxTxnHash.OrdinalLookup(txNumInFile)
gg := sn.Src().MakeGetter()
gg.Reset(offset)
// first byte txnHash check - reducing false-positives 256 times. Allows don't store and don't calculate full hash of entity - when checking many snapshots.
@@ -1111,7 +1111,7 @@ func (r *BlockReader) txnByHash(txnHash common.Hash, segments []*snapshotsync.Vi
txn, err := types.DecodeTransaction(txnRlp)
if err != nil {
- return nil, 0, false, err
+ return nil, 0, 0, false, err
}
txn.SetSender(sender) // see: https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer
@@ -1124,11 +1124,11 @@ func (r *BlockReader) txnByHash(txnHash common.Hash, segments []*snapshotsync.Vi
// final txnHash check - completely avoid false-positives
if txn.Hash() == txnHash {
- return txn, blockNum, true, nil
+ return txn, blockNum, idxTxnHash.BaseDataID() + txNumInFile + 1, true, nil
}
}
- return nil, 0, false, nil
+ return nil, 0, 0, false, nil
}
// TxnByIdxInBlock - doesn't include system-transactions in the begin/end of block
@@ -1178,24 +1178,23 @@ func (r *BlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNu
}
// TxnLookup - find blockNumber and txnID by txnHash
-func (r *BlockReader) TxnLookup(_ context.Context, tx kv.Getter, txnHash common.Hash) (uint64, bool, error) {
- n, err := rawdb.ReadTxLookupEntry(tx, txnHash)
+func (r *BlockReader) TxnLookup(_ context.Context, tx kv.Getter, txnHash common.Hash) (blockNum uint64, txNum uint64, ok bool, err error) {
+ blockNumPointer, txNumPointer, err := rawdb.ReadTxLookupEntry(tx, txnHash)
if err != nil {
- return 0, false, err
+ return 0, 0, false, err
}
- if n != nil {
- return *n, true, nil
+ if blockNumPointer != nil && txNumPointer != nil {
+ return *blockNumPointer, *txNumPointer, true, nil
}
txns := r.sn.ViewType(coresnaptype.Transactions)
defer txns.Close()
- _, blockNum, ok, err := r.txnByHash(txnHash, txns.Segments, nil)
+ _, blockNum, txNum, ok, err = r.txnByHash(txnHash, txns.Segments, nil)
if err != nil {
- return 0, false, err
+ return 0, 0, false, err
}
-
- return blockNum, ok, nil
+ return blockNum, txNum, ok, nil
}
func (r *BlockReader) FirstTxnNumNotInSnapshots() uint64 {
diff --git a/turbo/snapshotsync/freezeblocks/caplin_snapshots.go b/turbo/snapshotsync/freezeblocks/caplin_snapshots.go
index 2288ec40b47..6fd0708ff17 100644
--- a/turbo/snapshotsync/freezeblocks/caplin_snapshots.go
+++ b/turbo/snapshotsync/freezeblocks/caplin_snapshots.go
@@ -194,7 +194,7 @@ Loop:
snaptype.BeaconBlocks,
f.Version,
f.From, f.To,
- snapcfg.IsFrozen(s.cfg.ChainName, f))
+ true)
}
if err := sn.Open(s.dir); err != nil {
if errors.Is(err, os.ErrNotExist) {
@@ -250,7 +250,7 @@ Loop:
snaptype.BlobSidecars,
f.Version,
f.From, f.To,
- snapcfg.IsFrozen(s.cfg.ChainName, f))
+ true)
}
if err := sn.Open(s.dir); err != nil {
if errors.Is(err, os.ErrNotExist) {
diff --git a/turbo/stages/blockchain_test.go b/turbo/stages/blockchain_test.go
index ee06ae625aa..da3c6924c5d 100644
--- a/turbo/stages/blockchain_test.go
+++ b/turbo/stages/blockchain_test.go
@@ -544,7 +544,7 @@ func TestChainTxReorgs(t *testing.T) {
// removed tx
txs := types.Transactions{pastDrop, freshDrop}
for i, txn := range txs {
- if bn, _ := rawdb.ReadTxLookupEntry(tx, txn.Hash()); bn != nil {
+ if bn, _, _ := rawdb.ReadTxLookupEntry(tx, txn.Hash()); bn != nil {
t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
}
if rcpt, _, _, _, _ := readReceipt(tx, txn.Hash(), m); rcpt != nil {
@@ -555,18 +555,18 @@ func TestChainTxReorgs(t *testing.T) {
// added tx
txs = types.Transactions{pastAdd, freshAdd, futureAdd}
for i, txn := range txs {
- _, found, err := m.BlockReader.TxnLookup(m.Ctx, tx, txn.Hash())
+ _, _, found, err := m.BlockReader.TxnLookup(m.Ctx, tx, txn.Hash())
require.NoError(t, err)
require.True(t, found)
- if rcpt, _, _, _, _ := readReceipt(tx, txn.Hash(), m); rcpt == nil {
- t.Errorf("add %d: expected receipt to be found", i)
+ if rcpt, _, _, _, err := readReceipt(tx, txn.Hash(), m); rcpt == nil {
+ t.Errorf("add %d: expected receipt to be found, err %v", i, err)
}
}
// shared tx
txs = types.Transactions{postponed, swapped}
for i, txn := range txs {
- if bn, _ := rawdb.ReadTxLookupEntry(tx, txn.Hash()); bn == nil {
+ if bn, _, _ := rawdb.ReadTxLookupEntry(tx, txn.Hash()); bn == nil {
t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
}
@@ -578,7 +578,7 @@ func TestChainTxReorgs(t *testing.T) {
func readReceipt(db kv.TemporalTx, txHash libcommon.Hash, m *mock.MockSentry) (*types.Receipt, libcommon.Hash, uint64, uint64, error) {
// Retrieve the context of the receipt based on the transaction hash
- blockNumber, err := rawdb.ReadTxLookupEntry(db, txHash)
+ blockNumber, _, err := rawdb.ReadTxLookupEntry(db, txHash)
if err != nil {
return nil, libcommon.Hash{}, 0, 0, err
}
@@ -883,7 +883,7 @@ func doModesTest(t *testing.T, pm prune.Mode) error {
b, err := m.BlockReader.BlockByNumber(m.Ctx, tx, 1)
require.NoError(err)
for _, txn := range b.Transactions() {
- found, err := rawdb.ReadTxLookupEntry(tx, txn.Hash())
+ found, _, err := rawdb.ReadTxLookupEntry(tx, txn.Hash())
require.NoError(err)
require.Nil(found)
}
@@ -891,7 +891,7 @@ func doModesTest(t *testing.T, pm prune.Mode) error {
b, err := m.BlockReader.BlockByNumber(m.Ctx, tx, 1)
require.NoError(err)
for _, txn := range b.Transactions() {
- foundBlockNum, found, err := m.BlockReader.TxnLookup(context.Background(), tx, txn.Hash())
+ foundBlockNum, _, found, err := m.BlockReader.TxnLookup(context.Background(), tx, txn.Hash())
require.NoError(err)
require.True(found)
require.Equal(uint64(1), foundBlockNum)
@@ -1015,7 +1015,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
return
}
defer tx.Rollback()
- if st := state.New(m.NewStateReader(tx)); !st.Exist(theAddr) {
+ exist, err := state.New(m.NewStateReader(tx)).Exist(theAddr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !exist {
t.Error("expected account to exist")
}
tx.Rollback()
@@ -1025,7 +1029,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
t.Fatal(err)
}
if err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
- if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) {
+ exist, err := state.New(m.NewStateReader(tx)).Exist(theAddr)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("account should not exist")
}
return nil
@@ -1038,7 +1046,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
t.Fatal(err)
}
if err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
- if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) {
+ exist, err := state.New(m.NewStateReader(tx)).Exist(theAddr)
+ if err != nil {
+ return err
+ }
+ if exist {
t.Error("account should not exist")
}
return nil
@@ -1104,19 +1116,27 @@ func TestDoubleAccountRemoval(t *testing.T) {
st := state.New(m.NewStateReader(tx))
assert.NoError(t, err)
- assert.False(t, st.Exist(theAddr), "Contract should've been removed")
+ exist, err := st.Exist(theAddr)
+ assert.NoError(t, err)
+ assert.False(t, exist, "Contract should've been removed")
st = state.New(m.NewHistoryStateReader(1, tx))
assert.NoError(t, err)
- assert.False(t, st.Exist(theAddr), "Contract should not exist at block #0")
+ exist, err = st.Exist(theAddr)
+ assert.NoError(t, err)
+ assert.False(t, exist, "Contract should not exist at block #0")
st = state.New(m.NewHistoryStateReader(2, tx))
assert.NoError(t, err)
- assert.True(t, st.Exist(theAddr), "Contract should exist at block #1")
+ exist, err = st.Exist(theAddr)
+ assert.NoError(t, err)
+ assert.True(t, exist, "Contract should exist at block #1")
st = state.New(m.NewHistoryStateReader(3, tx))
assert.NoError(t, err)
- assert.True(t, st.Exist(theAddr), "Contract should exist at block #2")
+ exist, err = st.Exist(theAddr)
+ assert.NoError(t, err)
+ assert.True(t, exist, "Contract should exist at block #2")
}
// This is a regression test (i.e. as weird as it is, don't delete it ever), which
@@ -1609,7 +1629,10 @@ func TestCVE2020_26265(t *testing.T) {
reader := m.NewHistoryStateReader(2, tx)
statedb := state.New(reader)
- got := statedb.GetBalance(aa)
+ got, err := statedb.GetBalance(aa)
+ if err != nil {
+ t.Fatal(err)
+ }
if !got.Eq(new(uint256.Int).SetUint64(5)) {
t.Errorf("got %x exp %x", got, 5)
}
@@ -1871,7 +1894,11 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
}
exp := expectations[i]
if exp.exist {
- if !statedb.Exist(aa) {
+ exist, err := statedb.Exist(aa)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !exist {
t.Fatalf("block %d, expected %x to exist, it did not", blockNum, aa)
}
for slot, val := range exp.values {
@@ -1883,7 +1910,11 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
}
}
} else {
- if statedb.Exist(aa) {
+ exist, err := statedb.Exist(aa)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if exist {
t.Fatalf("block %d, expected %x to not exist, it did", blockNum, aa)
}
}
@@ -1989,7 +2020,11 @@ func TestInitThenFailCreateContract(t *testing.T) {
// Import the canonical chain
statedb := state.New(m.NewHistoryStateReader(2, tx))
- if got, exp := statedb.GetBalance(aa), uint64(100000); got.Uint64() != exp {
+ got, err := statedb.GetBalance(aa)
+ if err != nil {
+ return err
+ }
+ if exp := uint64(100000); got.Uint64() != exp {
t.Fatalf("Genesis err, got %v exp %v", got, exp)
}
// First block tries to create, but fails
@@ -1999,7 +2034,11 @@ func TestInitThenFailCreateContract(t *testing.T) {
t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
}
statedb = state.New(m.NewHistoryStateReader(1, tx))
- if got, exp := statedb.GetBalance(aa), uint64(100000); got.Uint64() != exp {
+ got, err := statedb.GetBalance(aa)
+ if err != nil {
+ return err
+ }
+ if exp := uint64(100000); got.Uint64() != exp {
t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
}
}
@@ -2199,7 +2238,10 @@ func TestEIP1559Transition(t *testing.T) {
statedb := state.New(m.NewHistoryStateReader(1, tx))
// 3: Ensure that miner received only the tx's tip.
- actual := statedb.GetBalance(block.Coinbase())
+ actual, err := statedb.GetBalance(block.Coinbase())
+ if err != nil {
+ return err
+ }
expected := new(uint256.Int).Add(
new(uint256.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GetPrice().Uint64()),
ethash.ConstantinopleBlockReward,
@@ -2209,7 +2251,11 @@ func TestEIP1559Transition(t *testing.T) {
}
// 4: Ensure the txn sender paid for the gasUsed * (tip + block baseFee).
- actual = new(uint256.Int).Sub(funds, statedb.GetBalance(addr1))
+ balance, err := statedb.GetBalance(addr1)
+ if err != nil {
+ return err
+ }
+ actual = new(uint256.Int).Sub(funds, balance)
expected = new(uint256.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GetPrice().Uint64() + block.BaseFee().Uint64()))
if actual.Cmp(expected) != 0 {
t.Fatalf("sender expenditure incorrect: expected %d, got %d", expected, actual)
@@ -2241,7 +2287,10 @@ func TestEIP1559Transition(t *testing.T) {
effectiveTip := block.Transactions()[0].GetPrice().Uint64() - block.BaseFee().Uint64()
// 6+5: Ensure that miner received only the tx's effective tip.
- actual := statedb.GetBalance(block.Coinbase())
+ actual, err := statedb.GetBalance(block.Coinbase())
+ if err != nil {
+ return err
+ }
expected := new(uint256.Int).Add(
new(uint256.Int).SetUint64(block.GasUsed()*effectiveTip),
ethash.ConstantinopleBlockReward,
@@ -2251,7 +2300,11 @@ func TestEIP1559Transition(t *testing.T) {
}
// 4: Ensure the txn sender paid for the gasUsed * (effectiveTip + block baseFee).
- actual = new(uint256.Int).Sub(funds, statedb.GetBalance(addr2))
+ balance, err := statedb.GetBalance(addr2)
+ if err != nil {
+ return err
+ }
+ actual = new(uint256.Int).Sub(funds, balance)
expected = new(uint256.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
if actual.Cmp(expected) != 0 {
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
diff --git a/turbo/stages/chain_makers_test.go b/turbo/stages/chain_makers_test.go
index 08dcd772cc2..e33f34ef5dd 100644
--- a/turbo/stages/chain_makers_test.go
+++ b/turbo/stages/chain_makers_test.go
@@ -118,14 +118,26 @@ func TestGenerateChain(t *testing.T) {
if big.NewInt(5).Cmp(current(m, tx).Number()) != 0 {
t.Errorf("wrong block number: %d", current(m, tx).Number())
}
- if !uint256.NewInt(989000).Eq(st.GetBalance(addr1)) {
- t.Errorf("wrong balance of addr1: %s", st.GetBalance(addr1))
+ balance, err := st.GetBalance(addr1)
+ if err != nil {
+ t.Error(err)
+ }
+ if !uint256.NewInt(989000).Eq(balance) {
+ t.Errorf("wrong balance of addr1: %s", balance)
+ }
+ balance, err = st.GetBalance(addr2)
+ if err != nil {
+ t.Error(err)
+ }
+ if !uint256.NewInt(10000).Eq(balance) {
+ t.Errorf("wrong balance of addr2: %s", balance)
}
- if !uint256.NewInt(10000).Eq(st.GetBalance(addr2)) {
- t.Errorf("wrong balance of addr2: %s", st.GetBalance(addr2))
+ balance, err = st.GetBalance(addr3)
+ if err != nil {
+ t.Error(err)
}
- if fmt.Sprintf("%s", st.GetBalance(addr3)) != "19687500000000001000" { //nolint
- t.Errorf("wrong balance of addr3: %s", st.GetBalance(addr3))
+ if fmt.Sprintf("%s", balance) != "19687500000000001000" { //nolint
+ t.Errorf("wrong balance of addr3: %s", balance)
}
if sentry_multi_client.EnableP2PReceipts {
diff --git a/txnprovider/txpool/pool.go b/txnprovider/txpool/pool.go
index 089cba73bca..d0600b3476a 100644
--- a/txnprovider/txpool/pool.go
+++ b/txnprovider/txpool/pool.go
@@ -1955,6 +1955,9 @@ func (p *TxPool) flush(ctx context.Context) (written uint64, err error) {
func (p *TxPool) flushLocked(tx kv.RwTx) (err error) {
for i, mt := range p.deletedTxns {
+ if mt == nil {
+ continue
+ }
id := mt.TxnSlot.SenderID
idHash := mt.TxnSlot.IDHash[:]
if !p.all.hasTxns(id) {