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

Pps sandbox #1860

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
787942a
fix::> Basic str ready
PsychoPunkSage May 7, 2024
9fe3466
fix::> parsing error reverting back to org
PsychoPunkSage May 7, 2024
8df2f60
fix::> RPC export properly working
PsychoPunkSage May 7, 2024
aafed1c
fix::> block with receipt output
PsychoPunkSage May 7, 2024
bf778fb
fix::> block with txns output
PsychoPunkSage May 7, 2024
b0cd907
fix::> remoaninig push
PsychoPunkSage May 7, 2024
a41b802
fix::> removed rpc response
PsychoPunkSage May 7, 2024
e09c801
add::> added response file
PsychoPunkSage May 7, 2024
301b7b9
fix::> New handler added
PsychoPunkSage May 8, 2024
7b66a6f
fix::> Test basic str ready
PsychoPunkSage May 8, 2024
07a205f
Merge branch 'NethermindEth:main' into pps-sandbox
PsychoPunkSage May 8, 2024
ba7e1b0
fix::> Test ready
PsychoPunkSage May 8, 2024
6380352
fix::> Implemented fn to get StateTrie
PsychoPunkSage May 10, 2024
c67cfd4
fix::> Expose NodeFromRoot fn
PsychoPunkSage May 10, 2024
399b283
fix::> impl fn to get nodes from root and a node parser
PsychoPunkSage May 10, 2024
d472131
fix::> impl handler JunoGetNodesFromRoot
PsychoPunkSage May 10, 2024
fc257c7
fix::> template
PsychoPunkSage May 10, 2024
2e7918b
fix::> Changed the fn name
PsychoPunkSage May 10, 2024
3fea2be
fix::> added new RPC_meth to methods
PsychoPunkSage May 10, 2024
94fc3f8
fix::> modified the code
PsychoPunkSage May 10, 2024
4a1a516
fix::> Handler test written
PsychoPunkSage May 11, 2024
893d38e
fix::> removed Juno
PsychoPunkSage May 11, 2024
b49f2f5
fix::> removed unnecessary files
PsychoPunkSage May 11, 2024
368ae2d
fix::> Test Written
PsychoPunkSage May 11, 2024
c2ada93
fix::> mock_state Node from Root partially implemented
PsychoPunkSage May 17, 2024
c921837
fix::> mock_state Node from Root partially implemented 1
PsychoPunkSage May 17, 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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ courtney/
__pycache__/
config/
.envrc
juno/
cmd/juno/pps_rpc.go
cmd/juno/rpc_respReceipts.go
cmd/juno/rpc_respTxns.go

Comment on lines +11 to 15
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just fyi, in a real PR these shouldn't be here

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I just wanted to keep previous code intact (I'm experimenting with it).
I thought this PR won't be merged so I kept it this way.

# pyenv
.python-version
12 changes: 12 additions & 0 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Reader interface {
Pending() (Pending, error)

Network() *utils.Network
// JunoGetNodesFromRoot(key *felt.Felt) (core.StateReader /*, StateCloser*/, error)
}

var (
Expand Down Expand Up @@ -109,6 +110,17 @@ func (b *Blockchain) StateCommitment() (*felt.Felt, error) {
})
}

// func (b *Blockchain) JunoGetNodesFromRoot(key *felt.Felt) (core.StateReader /*, StateCloser*/, error) {
// b.listener.OnRead("JunoGetNodesFromRoot")
// var state core.StateReader
// // var closer StateCloser
// return state, b.database.View(func(txn db.Transaction) error {
// var err error
// state, _, err = core.NewState(txn).NodeFromRoot(key)
// return err
// })
// }

Comment on lines +113 to +123
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with this

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned about writing some codes in blockchain.go file right? (in the message thread)
I was not sure about whether I'm doing correct thing here. So I just commented it.

// Height returns the latest block height. If blockchain is empty nil is returned.
func (b *Blockchain) Height() (uint64, error) {
b.listener.OnRead("Height")
Expand Down
5 changes: 5 additions & 0 deletions blockchain/pending.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package blockchain
import (
"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/core/trie"
)

type Pending struct {
Expand Down Expand Up @@ -65,3 +66,7 @@ func (p *PendingState) Class(classHash *felt.Felt) (*core.DeclaredClass, error)

return p.head.Class(classHash)
}

func (p *PendingState) GetGlobalTrie() (*trie.Trie, func() error, error) {
return p.head.GetGlobalTrie()
}
5 changes: 5 additions & 0 deletions core/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type StateReader interface {
ContractNonce(addr *felt.Felt) (*felt.Felt, error)
ContractStorage(addr, key *felt.Felt) (*felt.Felt, error)
Class(classHash *felt.Felt) (*DeclaredClass, error)
GetGlobalTrie() (*trie.Trie, func() error, error)
}

type State struct {
Expand Down Expand Up @@ -122,6 +123,10 @@ func (s *State) Root() (*felt.Felt, error) {
return crypto.PoseidonArray(stateVersion, storageRoot, classesRoot), nil
}

func (s *State) GetGlobalTrie() (*trie.Trie, func() error, error) {
return s.globalTrie(db.StateTrie, trie.NewTriePedersen)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are returning the state trie here, not the nodes from the root to a leaf

}

// storage returns a [core.Trie] that represents the Starknet global state in the given Txn context.
func (s *State) storage() (*trie.Trie, func() error, error) {
return s.globalTrie(db.StateTrie, trie.NewTriePedersen)
Expand Down
5 changes: 5 additions & 0 deletions core/state_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"

"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/core/trie"
"github.com/NethermindEth/juno/db"
)

Expand Down Expand Up @@ -87,3 +88,7 @@ func (s *stateSnapshot) Class(classHash *felt.Felt) (*DeclaredClass, error) {
}
return declaredClass, nil
}

func (s *stateSnapshot) GetGlobalTrie() (*trie.Trie, func() error, error) {
return s.state.GetGlobalTrie()
}
25 changes: 25 additions & 0 deletions core/trie/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ func (t *Trie) feltToKey(k *felt.Felt) Key {
return NewKey(t.height, kBytes[:])
}

func (t *Trie) FeltToKeyConverter(key *felt.Felt) Key {
return t.feltToKey(key)
}

// findCommonKey finds the set of common MSB bits in two key bitsets.
func findCommonKey(longerKey, shorterKey *Key) (Key, bool) {
divergentBit := findDivergentBit(longerKey, shorterKey)
Expand Down Expand Up @@ -135,6 +139,27 @@ type storageNode struct {
node *Node
}

type ParsedNodes struct {
k string
v string
}

func (t *Trie) NodeParser(nodes []storageNode) []ParsedNodes {
var parsedNodes []ParsedNodes
for _, node := range nodes {
parsableNode := ParsedNodes{
k: fmt.Sprintf("%v", node.key), // Assuming node.key can be stringified
v: fmt.Sprintf("%v", node.node),
}
parsedNodes = append(parsedNodes, parsableNode)
}
return parsedNodes
}

func (t *Trie) GetNodesFromRoot(key *Key) ([]storageNode, error) {
return t.nodesFromRoot(key)
}

// nodesFromRoot enumerates the set of [Node] objects that need to be traversed from the root
// of the Trie to the node which is given by the key.
// The [storageNode]s are returned in descending order beginning with the root.
Expand Down
56 changes: 56 additions & 0 deletions mocks/mock_state.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions rpc/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,43 @@ func nilToZero(f *felt.Felt) *felt.Felt {
}
return f
}

func (h *Handler) JunoGetBlockWithTxsAndReceipts(id BlockID) (*BlockWithTxs, *BlockWithReceipts, *jsonrpc.Error) {
rianhughes marked this conversation as resolved.
Show resolved Hide resolved
block, rpcErr := h.blockByID(&id)
if rpcErr != nil {
return nil, nil, rpcErr
}

blockStatus, rpcErr := h.blockStatus(id, block)
if rpcErr != nil {
return nil, nil, rpcErr
}

finalityStatus := TxnAcceptedOnL2
if blockStatus == BlockAcceptedL1 {
finalityStatus = TxnAcceptedOnL1
}

txs := make([]*Transaction, len(block.Transactions))
txsWithReceipts := make([]TransactionWithReceipt, len(block.Transactions))
for index, txn := range block.Transactions {
txs[index] = AdaptTransaction(txn)
r := block.Receipts[index]
txsWithReceipts[index] = TransactionWithReceipt{
Transaction: txs[index],
Receipt: AdaptReceipt(r, txn, finalityStatus, nil, 0, false),
}
}

return &BlockWithTxs{
Status: blockStatus,
BlockHeader: adaptBlockHeader(block.Header),
Transactions: txs,
},
&BlockWithReceipts{
Status: blockStatus,
BlockHeader: adaptBlockHeader(block.Header),
Transactions: txsWithReceipts,
},
nil
}
112 changes: 112 additions & 0 deletions rpc/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,3 +702,115 @@ func TestRpcBlockAdaptation(t *testing.T) {
require.Equal(t, &felt.Zero, blockWithTxHashes.BlockHeader.SequencerAddress)
})
}

func TestJunoGetBlockWithTxsAndReceipts(t *testing.T) {
blockId := map[string]rpc.BlockID{
"latest": {Latest: true},
"pending": {Pending: true},
"hash": {Hash: new(felt.Felt).SetUint64(1)},
"number": {Number: 1},
}

log := utils.NewNopZapLogger()
n := utils.Ptr(utils.Mainnet)
chain := blockchain.New(pebble.NewMemTest(t), n)
handler := rpc.New(chain, nil, nil, "", n, log)
for desc, id := range blockId {
t.Run(desc, func(t *testing.T) {
block, blockReceipt, rpcErr := handler.JunoGetBlockWithTxsAndReceipts(id)
assert.Nil(t, block)
assert.Nil(t, blockReceipt)
assert.Equal(t, rpc.ErrBlockNotFound, rpcErr)
})
}

mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)
mockReader := mocks.NewMockReader(mockCtrl)

t.Run("transaction DNE", func(t *testing.T) {
rianhughes marked this conversation as resolved.
Show resolved Hide resolved
blockID := rpc.BlockID{Number: 420}

mockReader.EXPECT().BlockByNumber(blockID.Number).Return(nil, db.ErrKeyNotFound) // Expecting BlockID DNE

respTxn, respRecp, rpcErr := handler.JunoGetBlockWithTxsAndReceipts(blockID)
assert.Nil(t, respTxn)
assert.Nil(t, respRecp)
assert.Equal(t, rpc.ErrBlockNotFound, rpcErr)
})

t.Run("l1head failure", func(t *testing.T) {
blockID := rpc.BlockID{Number: 420}
block := &core.Block{
Header: &core.Header{},
}

err := errors.New("l1 failure")
mockReader.EXPECT().BlockByNumber(blockID.Number).Return(block, nil) // Expecting BlockID to be valid
mockReader.EXPECT().L1Head().Return(nil, err) // Expecting L1head to fail

respTxn, respRecp, rpcErr := handler.JunoGetBlockWithTxsAndReceipts(blockID)
assert.Nil(t, respTxn)
assert.Nil(t, respRecp)
assert.Equal(t, rpc.ErrInternal.CloneWithData(err.Error()), rpcErr)
})

client := feeder.NewTestClient(t, n)
mainnetGw := adaptfeeder.New(client)

t.Run("pending block", func(t *testing.T) {
t.Skip()
Copy link
Contributor Author

@rianhughes rianhughes May 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t.Skip()?

block0, err := mainnetGw.BlockByNumber(context.Background(), 0)
require.NoError(t, err)

blockID := rpc.BlockID{Pending: true}

mockReader.EXPECT().Pending().Return(blockchain.Pending{Block: block0}, nil)
mockReader.EXPECT().L1Head().Return(&core.L1Head{}, nil)

respTxn, respRecp, rpcErr := handler.JunoGetBlockWithTxsAndReceipts(blockID)
header := respRecp.BlockHeader

var txsWithReceipt []rpc.TransactionWithReceipt
var txns []*rpc.Transaction
for i, tx := range block0.Transactions {
receipt := block0.Receipts[i]
adaptedTx := rpc.AdaptTransaction(tx)
txns = append(txns, adaptedTx)
txsWithReceipt = append(txsWithReceipt, rpc.TransactionWithReceipt{
Transaction: adaptedTx,
Receipt: rpc.AdaptReceipt(receipt, tx, rpc.TxnAcceptedOnL2, nil, 0, true),
})
}

assert.Nil(t, rpcErr)
assert.Equal(t, &rpc.BlockWithTxs{
Status: rpc.BlockPending,
BlockHeader: rpc.BlockHeader{
Hash: header.Hash,
ParentHash: header.ParentHash,
Number: header.Number,
NewRoot: header.NewRoot,
Timestamp: header.Timestamp,
SequencerAddress: header.SequencerAddress,
L1GasPrice: header.L1GasPrice,
StarknetVersion: header.StarknetVersion,
},
Transactions: txns,
}, respTxn)
assert.Equal(t, &rpc.BlockWithReceipts{
Status: rpc.BlockPending,
BlockHeader: rpc.BlockHeader{
Hash: header.Hash,
ParentHash: header.ParentHash,
Number: header.Number,
NewRoot: header.NewRoot,
Timestamp: header.Timestamp,
SequencerAddress: header.SequencerAddress,
L1GasPrice: header.L1GasPrice,
StarknetVersion: header.StarknetVersion,
},
Transactions: txsWithReceipt,
}, respRecp)
})
}
Loading