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

P2P sync update for 0.13.2 hashing scheme #2033

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e174a66
spec updated
AnkushinDaniil Jul 30, 2024
4c41a2c
Merge branch 'main' into proto-upgrade
AnkushinDaniil Jul 31, 2024
04fb4b1
Merge branch 'NethermindEth:main' into proto-upgrade
AnkushinDaniil Aug 1, 2024
da5b5fd
Merge branch 'NethermindEth:main' into proto-upgrade
AnkushinDaniil Aug 1, 2024
b15ddcd
linter fixed
AnkushinDaniil Aug 1, 2024
f445e7f
Merge branch 'NethermindEth:main' into proto-upgrade
AnkushinDaniil Aug 1, 2024
502ce09
linter fixed
AnkushinDaniil Aug 1, 2024
3b27bb0
TotalL1Gas updated
AnkushinDaniil Aug 2, 2024
8a1504a
hash is out of switch
AnkushinDaniil Aug 2, 2024
a3d114c
TransactionHash field added
AnkushinDaniil Aug 2, 2024
9428b1e
TransactionHash used
AnkushinDaniil Aug 2, 2024
ee0e47b
Merge branch 'main' into proto-upgrade
AnkushinDaniil Aug 2, 2024
21c3e1b
Merge branch 'NethermindEth:main' into proto-upgrade
AnkushinDaniil Aug 2, 2024
78b40c8
Merge branch 'proto-upgrade' of https://github.com/AnkushinDaniil/jun…
kirugan Aug 5, 2024
7358d7b
Fix p2p sync for new hashing scheme
kirugan Aug 7, 2024
e8fcd05
Remove debugging code, move hash updates logic to separate method
kirugan Aug 7, 2024
a972c13
Merge remote-tracking branch 'origin/main' into kirugan/proto-upgrade
kirugan Aug 8, 2024
0fe951e
Update mocks
kirugan Aug 8, 2024
28d57db
Add migration for p2p hash
kirugan Aug 9, 2024
f17294f
Add concurrency to p2p migration
kirugan Aug 12, 2024
eb3929d
Merge remote-tracking branch 'origin/main' into kirugan/proto-upgrade
kirugan Aug 12, 2024
af94b7b
Fix migration
kirugan Aug 12, 2024
25ad7f0
Fix adapting of reverted tx (receipt)
kirugan Aug 13, 2024
d235270
Remove additional info printing
kirugan Aug 13, 2024
9365b80
Change p2p sync logic
kirugan Aug 13, 2024
caaac8f
Remove unused parameter
kirugan Aug 13, 2024
34ff545
Prettify, simplify code
kirugan Aug 13, 2024
bc70292
Add 1 more test for adapter
kirugan Aug 13, 2024
2795c10
Add comment
kirugan Aug 13, 2024
ca010cf
Override nil sequencer address
kirugan Aug 14, 2024
2db28ec
Fix linter issues
kirugan Aug 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions adapters/core2p2p/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func AdaptBlockID(header *core.Header) *spec.BlockID {
}
}

func AdaptSignature(sig []*felt.Felt) *spec.ConsensusSignature {
func adaptSignature(sig []*felt.Felt) *spec.ConsensusSignature {
return &spec.ConsensusSignature{
R: AdaptFelt(sig[0]),
S: AdaptFelt(sig[1]),
Expand All @@ -45,11 +45,10 @@ func AdaptHeader(header *core.Header, commitments *core.BlockCommitments,
NLeaves: header.EventCount,
Root: AdaptHash(commitments.EventCommitment),
},
// todo fill receipts with receipt commitment
Receipts: AdaptHash(&felt.Zero),
Receipts: AdaptHash(commitments.ReceiptCommitment),
ProtocolVersion: header.ProtocolVersion,
GasPriceFri: AdaptUint128(header.GasPrice),
Signatures: utils.Map(header.Signatures, AdaptSignature),
Signatures: utils.Map(header.Signatures, adaptSignature),
StateDiffCommitment: &spec.StateDiffCommitment{
StateDiffLength: stateDiffLength,
Root: AdaptHash(stateDiffCommitment),
Expand Down
3 changes: 3 additions & 0 deletions adapters/core2p2p/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ func receiptCommon(r *core.TransactionReceipt) *spec.Receipt_Common {
var revertReason *string
if r.RevertReason != "" {
revertReason = &r.RevertReason
} else if r.Reverted {
kirugan marked this conversation as resolved.
Show resolved Hide resolved
// in some cases receipt marked as reverted may contain empty string in revert_reason
revertReason = utils.Ptr("")
}

return &spec.Receipt_Common{
Expand Down
5 changes: 2 additions & 3 deletions adapters/p2p2core/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ func AdaptBlockHeader(h *spec.SignedBlockHeader, eventsBloom *bloom.BloomFilter)
PriceInWei: AdaptUint128(h.DataGasPriceWei),
PriceInFri: AdaptUint128(h.DataGasPriceFri),
},
// todo(kirill) check prices
GasPrice: AdaptUint128(h.GasPriceWei),
GasPriceSTRK: AdaptUint128(h.GasPriceFri),
GasPrice: AdaptUint128(h.GasPriceFri),
GasPriceSTRK: AdaptUint128(h.GasPriceWei),
}
}

Expand Down
9 changes: 7 additions & 2 deletions adapters/p2p2core/felt.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package p2p2core

import (
"encoding/binary"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/p2p/starknet/spec"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -31,6 +32,10 @@
}

func AdaptUint128(u *spec.Uint128) *felt.Felt {
// todo handle u128
return &felt.Zero
bytes := make([]byte, 16)

Check failure on line 35 in adapters/p2p2core/felt.go

View workflow job for this annotation

GitHub Actions / lint

Magic number: 16, in <argument> detected (mnd)

binary.BigEndian.PutUint64(bytes[:8], u.High)
binary.BigEndian.PutUint64(bytes[8:], u.Low)

return new(felt.Felt).SetBytes(bytes)
}
2 changes: 1 addition & 1 deletion adapters/p2p2core/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func AdaptReceipt(r *spec.Receipt, txHash *felt.Felt) *core.TransactionReceipt {
L1ToL2Message: nil,
L2ToL1Message: utils.Map(common.MessagesSent, adaptMessageToL1),
TransactionHash: txHash,
Reverted: common.RevertReason != nil, // todo is it correct?
Reverted: common.RevertReason != nil, // in case it's empty string we should treat it as reverted
RevertReason: common.GetRevertReason(),
}
}
Expand Down
4 changes: 3 additions & 1 deletion adapters/p2p2core/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ func AdaptStateDiff(reader core.StateReader, contractDiffs []*spec.ContractDiff,
if diff.Nonce != nil {
nonces[*address] = AdaptFelt(diff.Nonce)
}
storageDiffs[*address] = utils.ToMap(diff.Values, adaptStoredValue)
if diff.Values != nil {
storageDiffs[*address] = utils.ToMap(diff.Values, adaptStoredValue)
}

// todo recheck this logic
if diff.ClassHash != nil {
Expand Down
59 changes: 53 additions & 6 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type Reader interface {
BlockByNumber(number uint64) (block *core.Block, err error)
BlockByHash(hash *felt.Felt) (block *core.Block, err error)

BlockP2PHashByNumber(number uint64) (hash *felt.Felt, err error)

HeadsHeader() (header *core.Header, err error)
BlockHeaderByNumber(number uint64) (header *core.Header, err error)
BlockHeaderByHash(hash *felt.Felt) (header *core.Header, err error)
Expand Down Expand Up @@ -206,12 +208,22 @@ func (b *Blockchain) BlockHeaderByHash(hash *felt.Felt) (*core.Header, error) {
})
}

func (b *Blockchain) BlockP2PHashByNumber(number uint64) (*felt.Felt, error) {
b.listener.OnRead("BlockP2PHashByNumber")
var hash *felt.Felt
return hash, b.database.View(func(txn db.Transaction) error {
var err error
hash, err = blockP2PHashByNumber(txn, number)
return err
})
}

func (b *Blockchain) StateUpdateByNumber(number uint64) (*core.StateUpdate, error) {
b.listener.OnRead("StateUpdateByNumber")
var update *core.StateUpdate
return update, b.database.View(func(txn db.Transaction) error {
var err error
update, err = stateUpdateByNumber(txn, number)
update, err = StateUpdateByNumber(txn, number)
return err
})
}
Expand Down Expand Up @@ -359,6 +371,11 @@ func (b *Blockchain) Store(block *core.Block, blockCommitments *core.BlockCommit
return err
}

// todo only for <0.13.2 blocks
if err := StoreP2PHash(txn, block, stateUpdate.StateDiff); err != nil {
return err
}

if err := StoreBlockCommitments(txn, block.Number, blockCommitments); err != nil {
return err
}
Expand All @@ -381,6 +398,36 @@ func (b *Blockchain) VerifyBlock(block *core.Block) error {
})
}

func StoreP2PHash(txn db.Transaction, block *core.Block, stateDiff *core.StateDiff) error {
originalParentHash := block.ParentHash
if block.Number > 0 {
prevP2PHash, err := blockP2PHashByNumber(txn, block.Number-1)
if err != nil {
return err
}
block.ParentHash = prevP2PHash
}

numBytes := core.MarshalBlockNumber(block.Number)
hash, _, err := core.Post0132Hash(block, stateDiff)
if err != nil {
return err
}
block.ParentHash = originalParentHash

hashBytes := hash.Bytes()
return txn.Set(db.P2PHash.Key(numBytes), hashBytes[:])
}

func blockP2PHashByNumber(txn db.Transaction, blockNumber uint64) (*felt.Felt, error) {
var blockHash *felt.Felt
numBytes := core.MarshalBlockNumber(blockNumber)
return blockHash, txn.Get(db.P2PHash.Key(numBytes), func(bytes []byte) error {
blockHash = new(felt.Felt).SetBytes(bytes)
return nil
})
}

func verifyBlock(txn db.Transaction, block *core.Block) error {
if err := checkBlockVersion(block.ProtocolVersion); err != nil {
return err
Expand Down Expand Up @@ -600,7 +647,7 @@ func storeStateUpdate(txn db.Transaction, blockNumber uint64, update *core.State
return txn.Set(db.StateUpdatesByBlockNumber.Key(numBytes), updateBytes)
}

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

var update *core.StateUpdate
Expand All @@ -617,14 +664,14 @@ func stateUpdateByHash(txn db.Transaction, hash *felt.Felt) (*core.StateUpdate,
var update *core.StateUpdate
return update, txn.Get(db.BlockHeaderNumbersByHash.Key(hash.Marshal()), func(val []byte) error {
var err error
update, err = stateUpdateByNumber(txn, binary.BigEndian.Uint64(val))
update, err = StateUpdateByNumber(txn, binary.BigEndian.Uint64(val))
return err
})
}

// 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,
newClasses map[felt.Felt]core.Class, force0132Hash bool,
) (*core.BlockCommitments, error) {
if !block.Hash.Equal(stateUpdate.BlockHash) {
return nil, errors.New("block hashes do not match")
Expand All @@ -637,7 +684,7 @@ func (b *Blockchain) SanityCheckNewHeight(block *core.Block, stateUpdate *core.S
return nil, err
}

return core.VerifyBlockHash(block, b.network, stateUpdate.StateDiff)
return core.VerifyBlockHash(block, b.network, stateUpdate.StateDiff, force0132Hash)
}

type txAndReceiptDBKey struct {
Expand Down Expand Up @@ -835,7 +882,7 @@ func (b *Blockchain) revertHead(txn db.Transaction) error {
}
numBytes := core.MarshalBlockNumber(blockNumber)

stateUpdate, err := stateUpdateByNumber(txn, blockNumber)
stateUpdate, err := StateUpdateByNumber(txn, blockNumber)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func TestSanityCheckNewHeight(t *testing.T) {
require.NoError(t, err)

stateUpdate := &core.StateUpdate{BlockHash: h1}
_, err = chain.SanityCheckNewHeight(mainnetBlock1, stateUpdate, nil)
_, err = chain.SanityCheckNewHeight(mainnetBlock1, stateUpdate, nil, false)
assert.EqualError(t, err, "block hashes do not match")
})

Expand All @@ -204,7 +204,7 @@ func TestSanityCheckNewHeight(t *testing.T) {
require.NoError(t, err)
stateUpdate := &core.StateUpdate{BlockHash: mainnetBlock1.Hash, NewRoot: h1}

_, err = chain.SanityCheckNewHeight(mainnetBlock1, stateUpdate, nil)
_, err = chain.SanityCheckNewHeight(mainnetBlock1, stateUpdate, nil, false)
assert.EqualError(t, err, "block's GlobalStateRoot does not match state update's NewRoot")
})
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/juno/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func getNetwork(head *core.Block, stateDiff *core.StateDiff) string {
}

for _, network := range networks {
if _, err := core.VerifyBlockHash(head, network, stateDiff); err == nil {
if _, err := core.VerifyBlockHash(head, network, stateDiff, false); err == nil {
return network.Name
}
}
Expand Down
32 changes: 18 additions & 14 deletions core/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type BlockCommitments struct {

// VerifyBlockHash verifies the block hash. Due to bugs in Starknet alpha, not all blocks have
// verifiable hashes.
func VerifyBlockHash(b *Block, network *utils.Network, stateDiff *StateDiff) (*BlockCommitments, error) {
func VerifyBlockHash(b *Block, network *utils.Network, stateDiff *StateDiff, force0132Hash bool) (*BlockCommitments, error) {
if len(b.Transactions) != len(b.Receipts) {
return nil, fmt.Errorf("len of transactions: %v do not match len of receipts: %v",
len(b.Transactions), len(b.Receipts))
Expand All @@ -92,7 +92,9 @@ func VerifyBlockHash(b *Block, network *utils.Network, stateDiff *StateDiff) (*B
unverifiableRange := metaInfo.UnverifiableRange

skipVerification := unverifiableRange != nil && b.Number >= unverifiableRange[0] && b.Number <= unverifiableRange[1] //nolint:gocritic
// todo should we still keep it after p2p ?
if force0132Hash {
skipVerification = false
}
if !skipVerification {
if err := VerifyTransactions(b.Transactions, network, b.ProtocolVersion); err != nil {
return nil, err
Expand All @@ -110,7 +112,7 @@ func VerifyBlockHash(b *Block, network *utils.Network, stateDiff *StateDiff) (*B
overrideSeq = fallbackSeq
}

hash, commitments, err := blockHash(b, stateDiff, network, overrideSeq)
hash, commitments, err := blockHash(b, stateDiff, network, overrideSeq, force0132Hash)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -141,18 +143,22 @@ func BlockHash(b *Block) (*felt.Felt, error) {
}

// blockHash computes the block hash, with option to override sequence address
func blockHash(b *Block, stateDiff *StateDiff, network *utils.Network, overrideSeqAddr *felt.Felt) (*felt.Felt,
*BlockCommitments, error,
) {
func blockHash(b *Block, stateDiff *StateDiff, network *utils.Network,
overrideSeqAddr *felt.Felt, force0132Hash bool) (*felt.Felt, *BlockCommitments, error) {
metaInfo := network.BlockHashMetaInfo

blockVer, err := ParseBlockVersion(b.ProtocolVersion)
if err != nil {
return nil, nil, err
usePre0132Hash := !force0132Hash
if usePre0132Hash {
blockVer, err := ParseBlockVersion(b.ProtocolVersion)
if err != nil {
return nil, nil, err
}

v0_13_2 := semver.MustParse("0.13.2")
usePre0132Hash = blockVer.LessThan(v0_13_2)
}
v0_13_2 := semver.MustParse("0.13.2")

if blockVer.LessThan(v0_13_2) {
if usePre0132Hash {
if b.Number < metaInfo.First07Block {
return pre07Hash(b, network.L2ChainIDFelt())
}
Expand Down Expand Up @@ -186,11 +192,11 @@ func pre07Hash(b *Block, chain *felt.Felt) (*felt.Felt, *BlockCommitments, error
}

func Post0132Hash(b *Block, stateDiff *StateDiff) (*felt.Felt, *BlockCommitments, error) {
wg := conc.NewWaitGroup()
var txCommitment, eCommitment, rCommitment, sdCommitment *felt.Felt
var sdLength uint64
var tErr, eErr, rErr error

wg := conc.NewWaitGroup()
wg.Go(func() {
txCommitment, tErr = transactionCommitmentPoseidon(b.Transactions)
})
Expand All @@ -200,12 +206,10 @@ func Post0132Hash(b *Block, stateDiff *StateDiff) (*felt.Felt, *BlockCommitments
wg.Go(func() {
rCommitment, rErr = receiptCommitment(b.Receipts)
})

wg.Go(func() {
sdLength = stateDiff.Length()
sdCommitment = stateDiff.Hash()
})

wg.Wait()

if tErr != nil {
Expand Down
12 changes: 6 additions & 6 deletions core/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func TestBlockHash(t *testing.T) {
block, err := gw.BlockByNumber(context.Background(), tc.number)
require.NoError(t, err)

commitments, err := core.VerifyBlockHash(block, &tc.chain, nil)
commitments, err := core.VerifyBlockHash(block, &tc.chain, nil, false)
assert.NoError(t, err)
assert.NotNil(t, commitments)
})
Expand All @@ -198,7 +198,7 @@ func TestBlockHash(t *testing.T) {
mainnetBlock1.Hash = h1

expectedErr := "can not verify hash in block header"
commitments, err := core.VerifyBlockHash(mainnetBlock1, &utils.Mainnet, nil)
commitments, err := core.VerifyBlockHash(mainnetBlock1, &utils.Mainnet, nil, false)
assert.EqualError(t, err, expectedErr)
assert.Nil(t, commitments)
})
Expand All @@ -209,7 +209,7 @@ func TestBlockHash(t *testing.T) {
block119802, err := goerliGW.BlockByNumber(context.Background(), 119802)
require.NoError(t, err)

commitments, err := core.VerifyBlockHash(block119802, &utils.Goerli, nil)
commitments, err := core.VerifyBlockHash(block119802, &utils.Goerli, nil, false)
assert.NoError(t, err)
assert.NotNil(t, commitments)
})
Expand All @@ -223,7 +223,7 @@ func TestBlockHash(t *testing.T) {
expectedErr := fmt.Sprintf("len of transactions: %v do not match len of receipts: %v",
len(mainnetBlock1.Transactions), len(mainnetBlock1.Receipts))

commitments, err := core.VerifyBlockHash(mainnetBlock1, &utils.Mainnet, nil)
commitments, err := core.VerifyBlockHash(mainnetBlock1, &utils.Mainnet, nil, false)
assert.EqualError(t, err, expectedErr)
assert.Nil(t, commitments)
})
Expand All @@ -237,7 +237,7 @@ func TestBlockHash(t *testing.T) {
"transaction hash (%v) at index: %v does not match receipt's hash (%v)",
mainnetBlock1.Transactions[1].Hash().String(), 1,
mainnetBlock1.Receipts[1].TransactionHash)
commitments, err := core.VerifyBlockHash(mainnetBlock1, &utils.Mainnet, nil)
commitments, err := core.VerifyBlockHash(mainnetBlock1, &utils.Mainnet, nil, false)
assert.EqualError(t, err, expectedErr)
assert.Nil(t, commitments)
})
Expand All @@ -261,7 +261,7 @@ func Test0132BlockHash(t *testing.T) {
su, err := gw.StateUpdate(context.Background(), test.blockNum)
require.NoError(t, err)

c, err := core.VerifyBlockHash(b, &utils.SepoliaIntegration, su.StateDiff)
c, err := core.VerifyBlockHash(b, &utils.SepoliaIntegration, su.StateDiff, false)
require.NoError(t, err)
assert.NotNil(t, c)
})
Expand Down
1 change: 1 addition & 0 deletions db/buckets.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
BlockCommitments
Temporary // used temporarily for migrations
SchemaIntermediateState
P2PHash
)

// Key flattens a prefix and series of byte arrays into a single []byte.
Expand Down
Loading
Loading