From 3077876e89c6fbb97db82cd334b083a3c35a77b5 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Sat, 12 Feb 2022 21:47:30 +0000 Subject: [PATCH 01/21] initial --- cmd/rpcdaemon/commands/erigon_block.go | 30 +++++++++++++++++++ .../snapshothashes/erigon-snapshots | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index fe9f90e0c39..c803b77af4b 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -58,3 +58,33 @@ func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (* return header, nil } + +func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return types.Block{}, err + } + defer tx.Rollback() + + currentHeader := rawdb.ReadCurrentHeader(tx) + currenttHeaderTime := currentHeader.Time + + firstHeader := rawdb.ReadHeaderByNumber(tx, 1) + firstHeaderTime := firstHeader.Time + + if currenttHeaderTime == timeStamp { + block := *rawdb.ReadCurrentBlock(tx) + return block, nil + } + + if firstHeaderTime == timeStamp { + block, err := rawdb.ReadBlockByNumber(tx, 1) + if err != nil { + return types.Block{}, err + } + return *block, nil + } + + return types.Block{}, nil + +} diff --git a/turbo/snapshotsync/snapshothashes/erigon-snapshots b/turbo/snapshotsync/snapshothashes/erigon-snapshots index e7e91d3c01f..bc35288c0ec 160000 --- a/turbo/snapshotsync/snapshothashes/erigon-snapshots +++ b/turbo/snapshotsync/snapshothashes/erigon-snapshots @@ -1 +1 @@ -Subproject commit e7e91d3c01f1da930cefbd3400631bd84b754bce +Subproject commit bc35288c0ec6a321a4a90165f7414b7ecff84c37 From 23925dc31efb5bb8a354f3b0c13f37292d0f6420 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Sun, 13 Feb 2022 18:07:38 +0000 Subject: [PATCH 02/21] binary search through blocks --- cmd/rpcdaemon/commands/erigon_block.go | 47 +++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index c803b77af4b..095219ed314 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -69,22 +69,61 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 currentHeader := rawdb.ReadCurrentHeader(tx) currenttHeaderTime := currentHeader.Time - firstHeader := rawdb.ReadHeaderByNumber(tx, 1) + var lowestNumber uint64 = 1 + highestNumber := currentHeader.Number.Uint64() + middleNumber := (highestNumber + lowestNumber) / 2 + + firstHeader := rawdb.ReadHeaderByNumber(tx, lowestNumber) firstHeaderTime := firstHeader.Time + middleHeader := rawdb.ReadHeaderByNumber(tx, middleNumber) + if currenttHeaderTime == timeStamp { - block := *rawdb.ReadCurrentBlock(tx) - return block, nil + block := rawdb.ReadCurrentBlock(tx) + return *block, nil } if firstHeaderTime == timeStamp { - block, err := rawdb.ReadBlockByNumber(tx, 1) + block, err := rawdb.ReadBlockByNumber(tx, lowestNumber) if err != nil { return types.Block{}, err } return *block, nil } + if middleHeader.Time == timeStamp { + block, err := rawdb.ReadBlockByNumber(tx, middleNumber) + if err != nil { + return types.Block{}, err + } + + return *block, nil + } + + for lowestNumber < highestNumber { + + if middleHeader.Time < timeStamp { + lowestNumber = middleNumber + } + + if middleHeader.Time > timeStamp { + highestNumber = middleNumber + } + + if middleHeader.Time == timeStamp { + block, err := rawdb.ReadBlockByNumber(tx, middleNumber) + if err != nil { + return types.Block{}, err + } + + return *block, nil + } + + middleNumber = (highestNumber + lowestNumber) / 2 + middleHeader = rawdb.ReadHeaderByNumber(tx, middleNumber) + + } + return types.Block{}, nil } From 4cd7ad6f1b903e00af69102a326b97b2e78c3a46 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 18:33:08 +0000 Subject: [PATCH 03/21] snapshot --- turbo/snapshotsync/snapshothashes/erigon-snapshots | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbo/snapshotsync/snapshothashes/erigon-snapshots b/turbo/snapshotsync/snapshothashes/erigon-snapshots index bc35288c0ec..e7e91d3c01f 160000 --- a/turbo/snapshotsync/snapshothashes/erigon-snapshots +++ b/turbo/snapshotsync/snapshothashes/erigon-snapshots @@ -1 +1 @@ -Subproject commit bc35288c0ec6a321a4a90165f7414b7ecff84c37 +Subproject commit e7e91d3c01f1da930cefbd3400631bd84b754bce From 67e232bd8a1c16bbba7ed886fc305ed56713b5cc Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 18:57:25 +0000 Subject: [PATCH 04/21] returning highest block --- cmd/rpcdaemon/commands/erigon_block.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index 095219ed314..9dd0a7be6ee 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -124,6 +124,11 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 } - return types.Block{}, nil + block, err := rawdb.ReadBlockByNumber(tx, highestNumber) + if err != nil { + return types.Block{}, err + } + + return *block, nil } From 941cb1ca34f84dcb103a9e6351b098e9ef87bace Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 19:48:48 +0000 Subject: [PATCH 05/21] oldest block is now 0 --- cmd/rpcdaemon/commands/erigon_block.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index 9dd0a7be6ee..c86a9c4b883 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -69,7 +69,7 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 currentHeader := rawdb.ReadCurrentHeader(tx) currenttHeaderTime := currentHeader.Time - var lowestNumber uint64 = 1 + var lowestNumber uint64 = 0 highestNumber := currentHeader.Number.Uint64() middleNumber := (highestNumber + lowestNumber) / 2 @@ -103,11 +103,11 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 for lowestNumber < highestNumber { if middleHeader.Time < timeStamp { - lowestNumber = middleNumber + lowestNumber = middleNumber + 1 } if middleHeader.Time > timeStamp { - highestNumber = middleNumber + highestNumber = middleNumber - 1 } if middleHeader.Time == timeStamp { @@ -121,6 +121,7 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 middleNumber = (highestNumber + lowestNumber) / 2 middleHeader = rawdb.ReadHeaderByNumber(tx, middleNumber) + fmt.Printf("middleNumber: %d, highestNumber: %d, lowestNumber: %d\n", middleNumber, highestNumber, lowestNumber) } From 019d06ffe5022b30e3e7b78b93d2ca41b975bbe9 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 19:49:37 +0000 Subject: [PATCH 06/21] multiple test written for getBlockByTimeStamp --- cmd/rpcdaemon/commands/eth_call_test.go | 116 ++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index b0c7ec16023..33402bb7bed 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -8,6 +8,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/kvcache" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/snapshotsync" @@ -42,3 +43,118 @@ func TestEthCallNonCanonical(t *testing.T) { } } } + +func TestGetBlockByTimeStampLatestTime(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) + + latestBlock := rawdb.ReadCurrentBlock(tx) + latestBlockTimeStamp := latestBlock.Header().Time + + block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block.Header().Time != latestBlockTimeStamp { + t.Errorf("Retrieved the wrong block. expected: %s got: %s", latestBlock.Hash(), block.Hash()) + } +} + +func TestGetBlockByTimeStampOldestTime(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("failed at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) + + oldestBlock, err := rawdb.ReadBlockByNumber(tx, 0) + if err != nil { + t.Error("couldn't retrieve oldest block") + } + oldestBlockTimeStamp := oldestBlock.Header().Time + + block, err := api.GetBlockByTimeStamp(ctx, oldestBlockTimeStamp) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block.Header().Time != 0 || block.Hash() != oldestBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", oldestBlock.Hash(), oldestBlockTimeStamp, block.Hash(), block.Header().Time) + } +} + +func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) + + latestBlock := rawdb.ReadCurrentBlock(tx) + latestBlockTimeStamp := latestBlock.Header().Time + + block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp+999999999999) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block.Header().Time != latestBlockTimeStamp || block.Hash() != latestBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", latestBlock.Hash(), latestBlockTimeStamp, block.Hash(), block.Header().Time) + } +} + +func TestGetBlockByTimeMiddle(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) + + currentHeader := rawdb.ReadCurrentHeader(tx) + oldestHeader := rawdb.ReadHeaderByNumber(tx, 0) + + middleNumber := (currentHeader.Number.Uint64() + oldestHeader.Number.Uint64()) / 2 + middleBlock, err := rawdb.ReadBlockByNumber(tx, middleNumber) + if err != nil { + t.Error("couldn't retrieve middle block") + } + + middleTimeStamp := middleBlock.Header().Time + + block, err := api.GetBlockByTimeStamp(ctx, middleTimeStamp) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block.Header().Time != middleTimeStamp || block.Hash() != middleBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", middleBlock.Hash(), middleTimeStamp, block.Hash(), block.Header().Time) + } +} From 9d0b4359966904e7df1d0a7d4da2c6126076c522 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 20:09:09 +0000 Subject: [PATCH 07/21] retrieved picked block time stamp --- cmd/rpcdaemon/commands/eth_call_test.go | 39 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index 33402bb7bed..be5ab8b7f28 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -65,8 +65,8 @@ func TestGetBlockByTimeStampLatestTime(t *testing.T) { t.Errorf("couldn't retrieve block %v", err) } - if block.Header().Time != latestBlockTimeStamp { - t.Errorf("Retrieved the wrong block. expected: %s got: %s", latestBlock.Hash(), block.Hash()) + if block.Header().Time != latestBlockTimeStamp || block.Hash() != latestBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", latestBlock.Hash(), latestBlockTimeStamp, block.Hash(), block.Header().Time) } } @@ -158,3 +158,38 @@ func TestGetBlockByTimeMiddle(t *testing.T) { t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", middleBlock.Hash(), middleTimeStamp, block.Hash(), block.Header().Time) } } + +func TestGetBlockByTimeStamp(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) + + highestBlockNumber := rawdb.ReadCurrentHeader(tx).Number + pickedBlock, err := rawdb.ReadBlockByNumber(tx, highestBlockNumber.Uint64()/3) + if err != nil { + t.Errorf("couldn't get block %v", pickedBlock.Number()) + } + + if pickedBlock == nil { + t.Error("couldn't retrieve picked block") + } + + pickedBlockTimeStamp := pickedBlock.Header().Time + + block, err := api.GetBlockByTimeStamp(ctx, pickedBlockTimeStamp) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block.Header().Time != pickedBlockTimeStamp || block.Hash() != pickedBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", pickedBlock.Hash(), pickedBlockTimeStamp, block.Hash(), block.Header().Time) + } +} From 039791e7b16bbcb0114512f5a14a3dbbdc813990 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 22:12:31 +0000 Subject: [PATCH 08/21] added into erigon_api --- cmd/rpcdaemon/commands/erigon_api.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/rpcdaemon/commands/erigon_api.go b/cmd/rpcdaemon/commands/erigon_api.go index 02624c58564..a195cc47176 100644 --- a/cmd/rpcdaemon/commands/erigon_api.go +++ b/cmd/rpcdaemon/commands/erigon_api.go @@ -19,6 +19,7 @@ type ErigonAPI interface { // Blocks related (see ./erigon_blocks.go) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) GetHeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) + GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) // Receipt related (see ./erigon_receipts.go) GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) From c37b99b2d7ebc2250b103393378cc4a4f94a6c21 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 22:21:08 +0000 Subject: [PATCH 09/21] returning pointer --- cmd/rpcdaemon/commands/erigon_api.go | 2 +- cmd/rpcdaemon/commands/erigon_block.go | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_api.go b/cmd/rpcdaemon/commands/erigon_api.go index a195cc47176..c784ab8a77b 100644 --- a/cmd/rpcdaemon/commands/erigon_api.go +++ b/cmd/rpcdaemon/commands/erigon_api.go @@ -19,7 +19,7 @@ type ErigonAPI interface { // Blocks related (see ./erigon_blocks.go) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) GetHeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) - GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) + GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (*types.Block, error) // Receipt related (see ./erigon_receipts.go) GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index c86a9c4b883..1b6ecccfbda 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -59,10 +59,10 @@ func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (* return header, nil } -func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) { +func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (*types.Block, error) { tx, err := api.db.BeginRo(ctx) if err != nil { - return types.Block{}, err + return nil, err } defer tx.Rollback() @@ -80,24 +80,24 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 if currenttHeaderTime == timeStamp { block := rawdb.ReadCurrentBlock(tx) - return *block, nil + return block, nil } if firstHeaderTime == timeStamp { block, err := rawdb.ReadBlockByNumber(tx, lowestNumber) if err != nil { - return types.Block{}, err + return nil, err } - return *block, nil + return block, nil } if middleHeader.Time == timeStamp { block, err := rawdb.ReadBlockByNumber(tx, middleNumber) if err != nil { - return types.Block{}, err + return nil, err } - return *block, nil + return block, nil } for lowestNumber < highestNumber { @@ -113,23 +113,22 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 if middleHeader.Time == timeStamp { block, err := rawdb.ReadBlockByNumber(tx, middleNumber) if err != nil { - return types.Block{}, err + return nil, err } - return *block, nil + return block, nil } middleNumber = (highestNumber + lowestNumber) / 2 middleHeader = rawdb.ReadHeaderByNumber(tx, middleNumber) - fmt.Printf("middleNumber: %d, highestNumber: %d, lowestNumber: %d\n", middleNumber, highestNumber, lowestNumber) } block, err := rawdb.ReadBlockByNumber(tx, highestNumber) if err != nil { - return types.Block{}, err + return nil, err } - return *block, nil + return block, nil } From 1c99cd654aeb92c7f95c203de636d88db0d1b748 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Mon, 14 Feb 2022 22:40:15 +0000 Subject: [PATCH 10/21] reverting c37b99b2d7ebc2250b103393378cc4a4f94a6c21 --- cmd/rpcdaemon/commands/erigon_api.go | 2 +- cmd/rpcdaemon/commands/erigon_block.go | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_api.go b/cmd/rpcdaemon/commands/erigon_api.go index c784ab8a77b..a195cc47176 100644 --- a/cmd/rpcdaemon/commands/erigon_api.go +++ b/cmd/rpcdaemon/commands/erigon_api.go @@ -19,7 +19,7 @@ type ErigonAPI interface { // Blocks related (see ./erigon_blocks.go) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) GetHeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) - GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (*types.Block, error) + GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) // Receipt related (see ./erigon_receipts.go) GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index 1b6ecccfbda..c86a9c4b883 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -59,10 +59,10 @@ func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (* return header, nil } -func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (*types.Block, error) { +func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) { tx, err := api.db.BeginRo(ctx) if err != nil { - return nil, err + return types.Block{}, err } defer tx.Rollback() @@ -80,24 +80,24 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 if currenttHeaderTime == timeStamp { block := rawdb.ReadCurrentBlock(tx) - return block, nil + return *block, nil } if firstHeaderTime == timeStamp { block, err := rawdb.ReadBlockByNumber(tx, lowestNumber) if err != nil { - return nil, err + return types.Block{}, err } - return block, nil + return *block, nil } if middleHeader.Time == timeStamp { block, err := rawdb.ReadBlockByNumber(tx, middleNumber) if err != nil { - return nil, err + return types.Block{}, err } - return block, nil + return *block, nil } for lowestNumber < highestNumber { @@ -113,22 +113,23 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 if middleHeader.Time == timeStamp { block, err := rawdb.ReadBlockByNumber(tx, middleNumber) if err != nil { - return nil, err + return types.Block{}, err } - return block, nil + return *block, nil } middleNumber = (highestNumber + lowestNumber) / 2 middleHeader = rawdb.ReadHeaderByNumber(tx, middleNumber) + fmt.Printf("middleNumber: %d, highestNumber: %d, lowestNumber: %d\n", middleNumber, highestNumber, lowestNumber) } block, err := rawdb.ReadBlockByNumber(tx, highestNumber) if err != nil { - return nil, err + return types.Block{}, err } - return block, nil + return *block, nil } From 8210d77322b946d8e464fc8804219625b6824920 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Tue, 15 Feb 2022 08:05:55 +0000 Subject: [PATCH 11/21] deleted print --- cmd/rpcdaemon/commands/erigon_block.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index c86a9c4b883..90b5e8d9960 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -121,7 +121,6 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 middleNumber = (highestNumber + lowestNumber) / 2 middleHeader = rawdb.ReadHeaderByNumber(tx, middleNumber) - fmt.Printf("middleNumber: %d, highestNumber: %d, lowestNumber: %d\n", middleNumber, highestNumber, lowestNumber) } From 4a5efcf96e29e39fcde8b3c4720832bd6ba1c91d Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Wed, 16 Feb 2022 10:28:01 +0000 Subject: [PATCH 12/21] proper rpc block response --- cmd/rpcdaemon/commands/erigon_api.go | 2 +- cmd/rpcdaemon/commands/erigon_block.go | 63 +++++++++++++++++++------- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_api.go b/cmd/rpcdaemon/commands/erigon_api.go index a195cc47176..5a5254d1d20 100644 --- a/cmd/rpcdaemon/commands/erigon_api.go +++ b/cmd/rpcdaemon/commands/erigon_api.go @@ -19,7 +19,7 @@ type ErigonAPI interface { // Blocks related (see ./erigon_blocks.go) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) GetHeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) - GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) + GetBlockByTimeStamp(ctx context.Context, timeStamp uint64, fullTx bool) (map[string]interface{}, error) // Receipt related (see ./erigon_receipts.go) GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index 90b5e8d9960..a326ca1191d 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -4,9 +4,11 @@ import ( "context" "fmt" + "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" ) @@ -59,10 +61,10 @@ func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (* return header, nil } -func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64) (types.Block, error) { +func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64, fullTx bool) (map[string]interface{}, error) { tx, err := api.db.BeginRo(ctx) if err != nil { - return types.Block{}, err + return nil, err } defer tx.Rollback() @@ -79,25 +81,30 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 middleHeader := rawdb.ReadHeaderByNumber(tx, middleNumber) if currenttHeaderTime == timeStamp { - block := rawdb.ReadCurrentBlock(tx) - return *block, nil + blockResponse, err := buildBlockResponse(tx, highestNumber, fullTx) + if err != nil { + return nil, err + } + + return blockResponse, nil } if firstHeaderTime == timeStamp { - block, err := rawdb.ReadBlockByNumber(tx, lowestNumber) + blockResponse, err := buildBlockResponse(tx, lowestNumber, fullTx) if err != nil { - return types.Block{}, err + return nil, err } - return *block, nil + + return blockResponse, nil } if middleHeader.Time == timeStamp { - block, err := rawdb.ReadBlockByNumber(tx, middleNumber) + blockResponse, err := buildBlockResponse(tx, middleNumber, fullTx) if err != nil { - return types.Block{}, err + return nil, err } - return *block, nil + return blockResponse, nil } for lowestNumber < highestNumber { @@ -111,24 +118,46 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 } if middleHeader.Time == timeStamp { - block, err := rawdb.ReadBlockByNumber(tx, middleNumber) + blockResponse, err := buildBlockResponse(tx, middleNumber, fullTx) if err != nil { - return types.Block{}, err + return nil, err } - - return *block, nil + return blockResponse, nil } middleNumber = (highestNumber + lowestNumber) / 2 middleHeader = rawdb.ReadHeaderByNumber(tx, middleNumber) + if middleHeader == nil { + return nil, nil + } } - block, err := rawdb.ReadBlockByNumber(tx, highestNumber) + blockResponse, err := buildBlockResponse(tx, highestNumber, fullTx) if err != nil { - return types.Block{}, err + return nil, err } + return blockResponse, nil - return *block, nil +} +func buildBlockResponse(db kv.Tx, blockNum uint64, fullTx bool) (map[string]interface{}, error) { + block, err := rawdb.ReadBlockByNumber(db, blockNum) + if err != nil { + return nil, err + } + + if block == nil { + return nil, nil + } + + response, err := ethapi.RPCMarshalBlock(block, true, fullTx) + + if err == nil && rpc.BlockNumber(block.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + return response, err } From 3dbc8856e2d2ed1fbb8ccccce5b5a6b8b7b0314a Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Wed, 16 Feb 2022 10:53:10 +0000 Subject: [PATCH 13/21] fixing test --- cmd/rpcdaemon/commands/eth_call_test.go | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index be5ab8b7f28..c76c2e3062e 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -60,13 +60,13 @@ func TestGetBlockByTimeStampLatestTime(t *testing.T) { latestBlock := rawdb.ReadCurrentBlock(tx) latestBlockTimeStamp := latestBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp) + block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block.Header().Time != latestBlockTimeStamp || block.Hash() != latestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", latestBlock.Hash(), latestBlockTimeStamp, block.Hash(), block.Header().Time) + if block["timestamp"] != latestBlockTimeStamp || block["hash"] != latestBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) } } @@ -89,13 +89,13 @@ func TestGetBlockByTimeStampOldestTime(t *testing.T) { } oldestBlockTimeStamp := oldestBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, oldestBlockTimeStamp) + block, err := api.GetBlockByTimeStamp(ctx, oldestBlockTimeStamp, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block.Header().Time != 0 || block.Hash() != oldestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", oldestBlock.Hash(), oldestBlockTimeStamp, block.Hash(), block.Header().Time) + if block["timestamp"] != 0 || block["hash"] != oldestBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", oldestBlock.Hash(), oldestBlockTimeStamp, block["hash"], block["timestamp"]) } } @@ -115,13 +115,13 @@ func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { latestBlock := rawdb.ReadCurrentBlock(tx) latestBlockTimeStamp := latestBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp+999999999999) + block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp+999999999999, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block.Header().Time != latestBlockTimeStamp || block.Hash() != latestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", latestBlock.Hash(), latestBlockTimeStamp, block.Hash(), block.Header().Time) + if block["timestamp"] != latestBlockTimeStamp || block["hash"] != latestBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) } } @@ -149,13 +149,13 @@ func TestGetBlockByTimeMiddle(t *testing.T) { middleTimeStamp := middleBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, middleTimeStamp) + block, err := api.GetBlockByTimeStamp(ctx, middleTimeStamp,false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block.Header().Time != middleTimeStamp || block.Hash() != middleBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", middleBlock.Hash(), middleTimeStamp, block.Hash(), block.Header().Time) + if block["timestamp"] != middleTimeStamp || block["hash"] != middleBlock.Hash(){ + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", middleBlock.Hash(), middleTimeStamp, block["hash"], block["timestamp"]) } } @@ -184,12 +184,12 @@ func TestGetBlockByTimeStamp(t *testing.T) { pickedBlockTimeStamp := pickedBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, pickedBlockTimeStamp) + block, err := api.GetBlockByTimeStamp(ctx, pickedBlockTimeStamp, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block.Header().Time != pickedBlockTimeStamp || block.Hash() != pickedBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time samp retrieve: %d", pickedBlock.Hash(), pickedBlockTimeStamp, block.Hash(), block.Header().Time) + if block["timestamp"] != pickedBlockTimeStamp || block["hash"] != pickedBlock.Hash() { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", pickedBlock.Hash(), pickedBlockTimeStamp, block["hash"], block["timestamp"]) } } From 1e6ceaf0acf087c40152e8d03b744d60ab963198 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Wed, 16 Feb 2022 19:17:15 +0000 Subject: [PATCH 14/21] returning lowest block --- cmd/rpcdaemon/commands/erigon_block.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index a326ca1191d..814fc24f52e 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -133,7 +133,7 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 } - blockResponse, err := buildBlockResponse(tx, highestNumber, fullTx) + blockResponse, err := buildBlockResponse(tx, lowestNumber, fullTx) if err != nil { return nil, err } From 8fc9138b0f972f26a8ca7f99d2c95947f6b65179 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Wed, 16 Feb 2022 19:18:03 +0000 Subject: [PATCH 15/21] lint --- cmd/rpcdaemon/commands/eth_call_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index c76c2e3062e..8e9be87a476 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -149,12 +149,12 @@ func TestGetBlockByTimeMiddle(t *testing.T) { middleTimeStamp := middleBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, middleTimeStamp,false) + block, err := api.GetBlockByTimeStamp(ctx, middleTimeStamp, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != middleTimeStamp || block["hash"] != middleBlock.Hash(){ + if block["timestamp"] != middleTimeStamp || block["hash"] != middleBlock.Hash() { t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", middleBlock.Hash(), middleTimeStamp, block["hash"], block["timestamp"]) } } From c7229ab40832d895570ffe4c59823096231fd447 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Thu, 17 Feb 2022 17:36:48 +0000 Subject: [PATCH 16/21] typo --- cmd/rpcdaemon/commands/eth_call_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index 8e9be87a476..b3759701f98 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -66,7 +66,7 @@ func TestGetBlockByTimeStampLatestTime(t *testing.T) { } if block["timestamp"] != latestBlockTimeStamp || block["hash"] != latestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) } } @@ -95,7 +95,7 @@ func TestGetBlockByTimeStampOldestTime(t *testing.T) { } if block["timestamp"] != 0 || block["hash"] != oldestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", oldestBlock.Hash(), oldestBlockTimeStamp, block["hash"], block["timestamp"]) + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", oldestBlock.Hash(), oldestBlockTimeStamp, block["hash"], block["timestamp"]) } } @@ -121,7 +121,7 @@ func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { } if block["timestamp"] != latestBlockTimeStamp || block["hash"] != latestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) } } @@ -155,7 +155,7 @@ func TestGetBlockByTimeMiddle(t *testing.T) { } if block["timestamp"] != middleTimeStamp || block["hash"] != middleBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", middleBlock.Hash(), middleTimeStamp, block["hash"], block["timestamp"]) + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", middleBlock.Hash(), middleTimeStamp, block["hash"], block["timestamp"]) } } @@ -190,6 +190,6 @@ func TestGetBlockByTimeStamp(t *testing.T) { } if block["timestamp"] != pickedBlockTimeStamp || block["hash"] != pickedBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected time stamp: %d\nblock hash retrieved: %s time stamp retrieved: %d", pickedBlock.Hash(), pickedBlockTimeStamp, block["hash"], block["timestamp"]) + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", pickedBlock.Hash(), pickedBlockTimeStamp, block["hash"], block["timestamp"]) } } From cfa72420fbbfd985545db65f54efe31a1cb82991 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Thu, 17 Feb 2022 18:05:42 +0000 Subject: [PATCH 17/21] fixed test --- cmd/rpcdaemon/commands/eth_call_test.go | 96 +++++++++++++++++++------ 1 file changed, 76 insertions(+), 20 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index b3759701f98..74d0f78bb4d 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -58,15 +58,26 @@ func TestGetBlockByTimeStampLatestTime(t *testing.T) { api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) latestBlock := rawdb.ReadCurrentBlock(tx) - latestBlockTimeStamp := latestBlock.Header().Time + response, err := ethapi.RPCMarshalBlock(latestBlock, true, false) - block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp, false) + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(latestBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimeStamp(ctx, latestBlock.Header().Time, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != latestBlockTimeStamp || block["hash"] != latestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) } } @@ -87,15 +98,27 @@ func TestGetBlockByTimeStampOldestTime(t *testing.T) { if err != nil { t.Error("couldn't retrieve oldest block") } - oldestBlockTimeStamp := oldestBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, oldestBlockTimeStamp, false) + response, err := ethapi.RPCMarshalBlock(oldestBlock, true, false) + + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(oldestBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimeStamp(ctx, oldestBlock.Header().Time, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != 0 || block["hash"] != oldestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", oldestBlock.Hash(), oldestBlockTimeStamp, block["hash"], block["timestamp"]) + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) } } @@ -113,15 +136,27 @@ func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) latestBlock := rawdb.ReadCurrentBlock(tx) - latestBlockTimeStamp := latestBlock.Header().Time - block, err := api.GetBlockByTimeStamp(ctx, latestBlockTimeStamp+999999999999, false) + response, err := ethapi.RPCMarshalBlock(latestBlock, true, false) + + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(latestBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimeStamp(ctx, latestBlock.Header().Time+999999999999, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != latestBlockTimeStamp || block["hash"] != latestBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", latestBlock.Hash(), latestBlockTimeStamp, block["hash"], block["timestamp"]) + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) } } @@ -147,15 +182,26 @@ func TestGetBlockByTimeMiddle(t *testing.T) { t.Error("couldn't retrieve middle block") } - middleTimeStamp := middleBlock.Header().Time + response, err := ethapi.RPCMarshalBlock(middleBlock, true, false) - block, err := api.GetBlockByTimeStamp(ctx, middleTimeStamp, false) + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(middleBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimeStamp(ctx, middleBlock.Header().Time, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != middleTimeStamp || block["hash"] != middleBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", middleBlock.Hash(), middleTimeStamp, block["hash"], block["timestamp"]) + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) } } @@ -181,15 +227,25 @@ func TestGetBlockByTimeStamp(t *testing.T) { if pickedBlock == nil { t.Error("couldn't retrieve picked block") } + response, err := ethapi.RPCMarshalBlock(pickedBlock, true, false) - pickedBlockTimeStamp := pickedBlock.Header().Time + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(pickedBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } - block, err := api.GetBlockByTimeStamp(ctx, pickedBlockTimeStamp, false) + block, err := api.GetBlockByTimeStamp(ctx, pickedBlock.Header().Time, false) if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != pickedBlockTimeStamp || block["hash"] != pickedBlock.Hash() { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", pickedBlock.Hash(), pickedBlockTimeStamp, block["hash"], block["timestamp"]) + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) } } From 6a79fb162609b90e418c49801403ab283de8d37c Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Thu, 17 Feb 2022 18:06:56 +0000 Subject: [PATCH 18/21] returning lowest-1 --- cmd/rpcdaemon/commands/erigon_block.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index 814fc24f52e..625bdf7cdc9 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -133,7 +133,7 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 } - blockResponse, err := buildBlockResponse(tx, lowestNumber, fullTx) + blockResponse, err := buildBlockResponse(tx, lowestNumber-1, fullTx) if err != nil { return nil, err } From 500e56946e22be688574a18137483f21c27b070a Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Thu, 17 Feb 2022 18:18:04 +0000 Subject: [PATCH 19/21] skip while loop for times too big or small --- cmd/rpcdaemon/commands/erigon_block.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index 625bdf7cdc9..d1489245dbc 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -80,7 +80,7 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 middleHeader := rawdb.ReadHeaderByNumber(tx, middleNumber) - if currenttHeaderTime == timeStamp { + if currenttHeaderTime <= timeStamp { blockResponse, err := buildBlockResponse(tx, highestNumber, fullTx) if err != nil { return nil, err @@ -89,7 +89,7 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 return blockResponse, nil } - if firstHeaderTime == timeStamp { + if firstHeaderTime >= timeStamp { blockResponse, err := buildBlockResponse(tx, lowestNumber, fullTx) if err != nil { return nil, err From 34eda5e99e052db7f940545bf7b1e45a218bcaa8 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Thu, 17 Feb 2022 19:00:30 +0000 Subject: [PATCH 20/21] added to readme --- cmd/rpcdaemon/README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cmd/rpcdaemon/README.md b/cmd/rpcdaemon/README.md index 6b724ec49e8..83ef81c8d77 100644 --- a/cmd/rpcdaemon/README.md +++ b/cmd/rpcdaemon/README.md @@ -262,17 +262,18 @@ The following table shows the current implementation status of Erigon's RPC daem | erigon_getLogsByHash | Yes | Erigon only | | erigon_forks | Yes | Erigon only | | erigon_issuance | Yes | Erigon only | +| erigon_getBlockByTimeStamp | Yes | Erigon only | | | | | | starknet_call | Yes | Starknet only | -| | | | -| bor_getSnapshot | Yes | Bor only | -| bor_getAuthor | Yes | Bor only | -| bor_getSnapshotAtHash | Yes | Bor only | -| bor_getSigners | Yes | Bor only | -| bor_getSignersAtHash | Yes | Bor only | -| bor_getCurrentProposer | Yes | Bor only | -| bor_getCurrentValidators | Yes | Bor only | -| bor_getRootHash | Yes | Bor only | +| | | | +| bor_getSnapshot | Yes | Bor only | +| bor_getAuthor | Yes | Bor only | +| bor_getSnapshotAtHash | Yes | Bor only | +| bor_getSigners | Yes | Bor only | +| bor_getSignersAtHash | Yes | Bor only | +| bor_getCurrentProposer | Yes | Bor only | +| bor_getCurrentValidators | Yes | Bor only | +| bor_getRootHash | Yes | Bor only | This table is constantly updated. Please visit again. From 8fc76a45157707681e38b56729350036b7dd8c46 Mon Sep 17 00:00:00 2001 From: Enrique Avila Asapche Date: Sat, 19 Feb 2022 18:15:51 +0100 Subject: [PATCH 21/21] using sort.Search --- cmd/rpcdaemon/commands/erigon_block.go | 53 ++++++++------------------ 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index d1489245dbc..eaac6eec235 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -3,6 +3,7 @@ package commands import ( "context" "fmt" + "sort" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" @@ -70,16 +71,11 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 currentHeader := rawdb.ReadCurrentHeader(tx) currenttHeaderTime := currentHeader.Time - - var lowestNumber uint64 = 0 highestNumber := currentHeader.Number.Uint64() - middleNumber := (highestNumber + lowestNumber) / 2 - firstHeader := rawdb.ReadHeaderByNumber(tx, lowestNumber) + firstHeader := rawdb.ReadHeaderByNumber(tx, 0) firstHeaderTime := firstHeader.Time - middleHeader := rawdb.ReadHeaderByNumber(tx, middleNumber) - if currenttHeaderTime <= timeStamp { blockResponse, err := buildBlockResponse(tx, highestNumber, fullTx) if err != nil { @@ -90,7 +86,7 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 } if firstHeaderTime >= timeStamp { - blockResponse, err := buildBlockResponse(tx, lowestNumber, fullTx) + blockResponse, err := buildBlockResponse(tx, 0, fullTx) if err != nil { return nil, err } @@ -98,47 +94,28 @@ func (api *ErigonImpl) GetBlockByTimeStamp(ctx context.Context, timeStamp uint64 return blockResponse, nil } - if middleHeader.Time == timeStamp { - blockResponse, err := buildBlockResponse(tx, middleNumber, fullTx) - if err != nil { - return nil, err - } + blockNum := sort.Search(int(currentHeader.Number.Uint64()), func(blockNum int) bool { + currentHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) - return blockResponse, nil - } + return currentHeader.Time >= timeStamp + }) - for lowestNumber < highestNumber { - - if middleHeader.Time < timeStamp { - lowestNumber = middleNumber + 1 - } + resultingHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) - if middleHeader.Time > timeStamp { - highestNumber = middleNumber - 1 - } - - if middleHeader.Time == timeStamp { - blockResponse, err := buildBlockResponse(tx, middleNumber, fullTx) - if err != nil { - return nil, err - } - return blockResponse, nil - } - - middleNumber = (highestNumber + lowestNumber) / 2 - middleHeader = rawdb.ReadHeaderByNumber(tx, middleNumber) - if middleHeader == nil { - return nil, nil + if resultingHeader.Time > timeStamp { + response, err := buildBlockResponse(tx, uint64(blockNum)-1, fullTx) + if err != nil { + return nil, err } - + return response, nil } - blockResponse, err := buildBlockResponse(tx, lowestNumber-1, fullTx) + response, err := buildBlockResponse(tx, uint64(blockNum), fullTx) if err != nil { return nil, err } - return blockResponse, nil + return response, nil } func buildBlockResponse(db kv.Tx, blockNum uint64, fullTx bool) (map[string]interface{}, error) {