Skip to content

Commit

Permalink
Implement starknet_getMessageStatus (#2184)
Browse files Browse the repository at this point in the history
Signed-off-by: Rian Hughes <ryanhughes4500@hotmail.com>
Signed-off-by: Kirill <paltsev.kir@gmail.com>
Co-authored-by: Aneeque <aneequesafdar@gmail.com>
Co-authored-by: Kirill <paltsev.kir@gmail.com>
  • Loading branch information
3 people authored Nov 19, 2024
1 parent 226c571 commit 7286fe7
Show file tree
Hide file tree
Showing 25 changed files with 10,502 additions and 51 deletions.
61 changes: 51 additions & 10 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"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 @@ type Reader interface {
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) (l1HandlerTxnHash *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 @@ func (b *Blockchain) Height() (uint64, error) {
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 (b *Blockchain) HeadsHeader() (*core.Header, error) {
}

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) StateUpdateByHash(hash *felt.Felt) (*core.StateUpdate, erro
})
}

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 @@ func (b *Blockchain) Store(block *core.Block, blockCommitments *core.BlockCommit
return err
}

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

if err := b.storeEmptyPending(txn, block.Header); err != nil {
return err
}
Expand Down Expand Up @@ -497,7 +513,7 @@ func BlockByNumber(txn db.Transaction, number uint64) (*core.Block, error) {

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 @@ func BlockByNumber(txn db.Transaction, number uint64) (*core.Block, error) {
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,18 @@ func blockByHash(txn db.Transaction, hash *felt.Felt) (*core.Block, error) {
})
}

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

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

Expand Down Expand Up @@ -622,6 +650,14 @@ func stateUpdateByHash(txn db.Transaction, hash *felt.Felt) (*core.StateUpdate,
})
}

func l1HandlerTxnHashByMsgHash(txn db.Transaction, l1HandlerMsgHash *common.Hash) (*felt.Felt, error) {
l1HandlerTxnHash := new(felt.Felt)
return l1HandlerTxnHash, txn.Get(db.L1HandlerTxnHashByMsgHash.Key(l1HandlerMsgHash.Bytes()), func(val []byte) error {
l1HandlerTxnHash.Unmarshal(val)
return nil
})
}

// 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 +797,7 @@ func (b *Blockchain) HeadState() (core.StateReader, StateCloser, error) {
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 +851,7 @@ func (b *Blockchain) EventFilter(from *felt.Felt, keys [][]felt.Felt) (*EventFil
return nil, err
}

latest, err := chainHeight(txn)
latest, err := ChainHeight(txn)
if err != nil {
return nil, err
}
Expand All @@ -831,7 +867,7 @@ func (b *Blockchain) RevertHead() error {
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 +882,7 @@ func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) {
}

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 +969,11 @@ func removeTxsAndReceipts(txn db.Transaction, blockNumber, numTxs uint64) error
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
}
}
}

return nil
Expand Down
20 changes: 20 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 @@ -239,6 +240,7 @@ func TestStore(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, stateUpdate0, got0Update)
})

t.Run("add block to non-empty blockchain", func(t *testing.T) {
block1, err := gw.BlockByNumber(context.Background(), 1)
require.NoError(t, err)
Expand Down Expand Up @@ -268,6 +270,24 @@ func TestStore(t *testing.T) {
})
}

func TestStoreL1HandlerTxnHash(t *testing.T) {
client := feeder.NewTestClient(t, &utils.Sepolia)
gw := adaptfeeder.New(client)
chain := blockchain.New(pebble.NewMemTest(t), &utils.Sepolia)
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)
}

func TestBlockCommitments(t *testing.T) {
chain := blockchain.New(pebble.NewMemTest(t), &utils.Mainnet)
client := feeder.NewTestClient(t, &utils.Mainnet)
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

0 comments on commit 7286fe7

Please sign in to comment.