Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement starknet_getMessageStatus #2184

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
69 changes: 59 additions & 10 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"github.com/NethermindEth/juno/db"
"github.com/NethermindEth/juno/encoder"
"github.com/NethermindEth/juno/utils"
"github.com/ethereum/go-ethereum/common"
)

//go:generate mockgen -destination=../mocks/mock_blockchain.go -package=mocks github.com/NethermindEth/juno/blockchain Reader
Expand All @@ -34,6 +35,7 @@
Receipt(hash *felt.Felt) (receipt *core.TransactionReceipt, blockHash *felt.Felt, blockNumber uint64, err error)
StateUpdateByNumber(number uint64) (update *core.StateUpdate, err error)
StateUpdateByHash(hash *felt.Felt) (update *core.StateUpdate, err error)
L1HandlerTxnHash(msgHash *common.Hash) (l1HandlerTxnHashes *felt.Felt, err error)

HeadState() (core.StateReader, StateCloser, error)
StateAtBlockHash(blockHash *felt.Felt) (core.StateReader, StateCloser, error)
Expand Down Expand Up @@ -115,12 +117,12 @@
var height uint64
return height, b.database.View(func(txn db.Transaction) error {
var err error
height, err = chainHeight(txn)
height, err = ChainHeight(txn)
return err
})
}

func chainHeight(txn db.Transaction) (uint64, error) {
func ChainHeight(txn db.Transaction) (uint64, error) {
var height uint64
return height, txn.Get(db.ChainHeight.Key(), func(val []byte) error {
height = binary.BigEndian.Uint64(val)
Expand Down Expand Up @@ -150,15 +152,15 @@
}

func head(txn db.Transaction) (*core.Block, error) {
height, err := chainHeight(txn)
height, err := ChainHeight(txn)
if err != nil {
return nil, err
}
return BlockByNumber(txn, height)
}

func headsHeader(txn db.Transaction) (*core.Header, error) {
height, err := chainHeight(txn)
height, err := ChainHeight(txn)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -226,6 +228,16 @@
})
}

func (b *Blockchain) L1HandlerTxnHash(msgHash *common.Hash) (*felt.Felt, error) {
b.listener.OnRead("L1HandlerTxnHash")
var l1HandlerTxnHash *felt.Felt
return l1HandlerTxnHash, b.database.View(func(txn db.Transaction) error {
var err error
l1HandlerTxnHash, err = l1HandlerTxnHashByMsgHash(txn, msgHash)
return err
})
}

// TransactionByBlockNumberAndIndex gets the transaction for a given block number and index.
func (b *Blockchain) TransactionByBlockNumberAndIndex(blockNumber, index uint64) (core.Transaction, error) {
b.listener.OnRead("TransactionByBlockNumberAndIndex")
Expand Down Expand Up @@ -363,6 +375,10 @@
return err
}

if err := StoreL1HandlerMsgHashes(txn, block.Transactions); err != nil {
return err
}

Check warning on line 380 in blockchain/blockchain.go

View check run for this annotation

Codecov / codecov/patch

blockchain/blockchain.go#L379-L380

Added lines #L379 - L380 were not covered by tests

if err := b.storeEmptyPending(txn, block.Header); err != nil {
return err
}
Expand Down Expand Up @@ -497,7 +513,7 @@

block := new(core.Block)
block.Header = header
block.Transactions, err = transactionsByBlockNumber(txn, number)
block.Transactions, err = TransactionsByBlockNumber(txn, number)
if err != nil {
return nil, err
}
Expand All @@ -509,7 +525,7 @@
return block, nil
}

func transactionsByBlockNumber(txn db.Transaction, number uint64) ([]core.Transaction, error) {
func TransactionsByBlockNumber(txn db.Transaction, number uint64) ([]core.Transaction, error) {
iterator, err := txn.NewIterator()
if err != nil {
return nil, err
Expand Down Expand Up @@ -589,6 +605,19 @@
})
}

func StoreL1HandlerMsgHashes(dbTxn db.Transaction, blockTxns []core.Transaction) error {
for _, txn := range blockTxns {
if l1Handler, ok := (txn).(*core.L1HandlerTransaction); ok {
l1HandlerTxnHashBytes := txn.Hash().Bytes()
err := dbTxn.Set(db.L1HandlerTxnHashByMsgHash.Key(l1Handler.MessageHash()), l1HandlerTxnHashBytes[:])
if err != nil {
return err
}

Check warning on line 615 in blockchain/blockchain.go

View check run for this annotation

Codecov / codecov/patch

blockchain/blockchain.go#L614-L615

Added lines #L614 - L615 were not covered by tests
}
}
return nil
}

func storeStateUpdate(txn db.Transaction, blockNumber uint64, update *core.StateUpdate) error {
numBytes := core.MarshalBlockNumber(blockNumber)

Expand Down Expand Up @@ -622,6 +651,21 @@
})
}

func l1HandlerTxnHashByMsgHash(txn db.Transaction, l1HandlerMsgHash *common.Hash) (*felt.Felt, error) {
var raw []byte
err := txn.Get(db.L1HandlerTxnHashByMsgHash.Key(l1HandlerMsgHash.Bytes()), func(val []byte) error {
if len(val) == 0 {
rianhughes marked this conversation as resolved.
Show resolved Hide resolved
return db.ErrKeyNotFound
}

Check warning on line 659 in blockchain/blockchain.go

View check run for this annotation

Codecov / codecov/patch

blockchain/blockchain.go#L658-L659

Added lines #L658 - L659 were not covered by tests
raw = val
return nil
})
if err != nil {
return nil, err
}
return new(felt.Felt).SetBytes(raw), nil
rianhughes marked this conversation as resolved.
Show resolved Hide resolved
}

// SanityCheckNewHeight checks integrity of a block and resulting state update
func (b *Blockchain) SanityCheckNewHeight(block *core.Block, stateUpdate *core.StateUpdate,
newClasses map[felt.Felt]core.Class,
Expand Down Expand Up @@ -761,7 +805,7 @@
return nil, nil, err
}

_, err = chainHeight(txn)
_, err = ChainHeight(txn)
if err != nil {
return nil, nil, utils.RunAndWrapOnError(txn.Discard, err)
}
Expand Down Expand Up @@ -815,7 +859,7 @@
return nil, err
}

latest, err := chainHeight(txn)
latest, err := ChainHeight(txn)
if err != nil {
return nil, err
}
Expand All @@ -831,7 +875,7 @@
func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) {
var reverseStateDiff *core.StateDiff
return reverseStateDiff, b.database.View(func(txn db.Transaction) error {
blockNumber, err := chainHeight(txn)
blockNumber, err := ChainHeight(txn)
if err != nil {
return err
}
Expand All @@ -846,7 +890,7 @@
}

func (b *Blockchain) revertHead(txn db.Transaction) error {
blockNumber, err := chainHeight(txn)
blockNumber, err := ChainHeight(txn)
if err != nil {
return err
}
Expand Down Expand Up @@ -933,6 +977,11 @@
if err = txn.Delete(db.TransactionBlockNumbersAndIndicesByHash.Key(reorgedTxn.Hash().Marshal())); err != nil {
return err
}
if l1handler, ok := reorgedTxn.(*core.L1HandlerTransaction); ok {
if err = txn.Delete(db.L1HandlerTxnHashByMsgHash.Key(l1handler.MessageHash())); err != nil {
return err
}

Check warning on line 983 in blockchain/blockchain.go

View check run for this annotation

Codecov / codecov/patch

blockchain/blockchain.go#L981-L983

Added lines #L981 - L983 were not covered by tests
}
}

return nil
Expand Down
31 changes: 31 additions & 0 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/NethermindEth/juno/mocks"
adaptfeeder "github.com/NethermindEth/juno/starknetdata/feeder"
"github.com/NethermindEth/juno/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
Expand Down Expand Up @@ -238,7 +239,13 @@ func TestStore(t *testing.T) {
got0Update, err := chain.StateUpdateByHash(block0.Hash)
require.NoError(t, err)
assert.Equal(t, stateUpdate0, got0Update)

nonExistentMsgHash := common.HexToHash("0xcoffeebabe")
rianhughes marked this conversation as resolved.
Show resolved Hide resolved
hash, err := chain.L1HandlerTxnHash(&nonExistentMsgHash)
require.Nil(t, hash)
require.Equal(t, db.ErrKeyNotFound, err)
})

t.Run("add block to non-empty blockchain", func(t *testing.T) {
block1, err := gw.BlockByNumber(context.Background(), 1)
require.NoError(t, err)
Expand All @@ -265,6 +272,30 @@ func TestStore(t *testing.T) {
got1Update, err := chain.StateUpdateByNumber(1)
require.NoError(t, err)
assert.Equal(t, stateUpdate1, got1Update)

nonExistentMsgHash := common.HexToHash("0xcoffeebabe")
hash, err := chain.L1HandlerTxnHash(&nonExistentMsgHash)
require.Nil(t, hash)
require.Equal(t, db.ErrKeyNotFound, err)
})

t.Run("add block with L1 Handler Txn", func(t *testing.T) {
client := feeder.NewTestClient(t, &utils.Sepolia)
gw := adaptfeeder.New(client)
chain := blockchain.New(pebble.NewMemTest(t), &utils.Sepolia)
var block *core.Block
var stateUpdate *core.StateUpdate
for i := range uint64(7) {
block, err = gw.BlockByNumber(context.Background(), i)
require.NoError(t, err)
stateUpdate, err = gw.StateUpdate(context.Background(), i)
require.NoError(t, err)
require.NoError(t, chain.Store(block, &emptyCommitments, stateUpdate, nil))
}
l1HandlerMsgHash := common.HexToHash("0x42e76df4e3d5255262929c27132bd0d295a8d3db2cfe63d2fcd061c7a7a7ab34")
l1HandlerTxnHash, err := chain.L1HandlerTxnHash(&l1HandlerMsgHash)
require.NoError(t, err)
require.Equal(t, utils.HexToFelt(t, "0x785c2ada3f53fbc66078d47715c27718f92e6e48b96372b36e5197de69b82b5"), l1HandlerTxnHash)
})
}

Expand Down
2 changes: 1 addition & 1 deletion blockchain/event_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type FilteredEvent struct {
//nolint:gocyclo
func (e *EventFilter) Events(cToken *ContinuationToken, chunkSize uint64) ([]*FilteredEvent, *ContinuationToken, error) {
var matchedEvents []*FilteredEvent
latest, err := chainHeight(e.txn)
latest, err := ChainHeight(e.txn)
if err != nil {
return nil, nil, err
}
Expand Down
Loading