55 "encoding/binary"
66 "errors"
77 "fmt"
8- "sync/atomic"
98
109 "github.com/Masterminds/semver/v3"
1110 "github.com/NethermindEth/juno/core"
@@ -39,14 +38,11 @@ type Reader interface {
3938 HeadState () (core.StateReader , StateCloser , error )
4039 StateAtBlockHash (blockHash * felt.Felt ) (core.StateReader , StateCloser , error )
4140 StateAtBlockNumber (blockNumber uint64 ) (core.StateReader , StateCloser , error )
42- PendingState () (core.StateReader , StateCloser , error )
4341
4442 BlockCommitmentsByNumber (blockNumber uint64 ) (* core.BlockCommitments , error )
4543
4644 EventFilter (from * felt.Felt , keys [][]felt.Felt ) (EventFilterer , error )
4745
48- Pending () (* Pending , error )
49-
5046 Network () * utils.Network
5147}
5248
5652 SupportedStarknetVersion = semver .MustParse ("0.13.3" )
5753)
5854
59- func checkBlockVersion (protocolVersion string ) error {
55+ func CheckBlockVersion (protocolVersion string ) error {
6056 blockVer , err := core .ParseBlockVersion (protocolVersion )
6157 if err != nil {
6258 return err
@@ -81,22 +77,21 @@ func copyWithoutPatch(v *semver.Version) *semver.Version {
8177
8278var _ Reader = (* Blockchain )(nil )
8379
84- // Todo: Remove after pending is moved to sychcroniser
85- var pending atomic.Pointer [Pending ]
86-
8780// Blockchain is responsible for keeping track of all things related to the Starknet blockchain
8881type Blockchain struct {
89- network * utils.Network
90- database db.DB
91- listener EventListener
82+ network * utils.Network
83+ database db.DB
84+ listener EventListener
85+ pendingBlockFn func () * core.Block
9286}
9387
94- func New (database db.DB , network * utils.Network ) * Blockchain {
88+ func New (database db.DB , network * utils.Network , pendingBlockFn func () * core. Block ) * Blockchain {
9589 RegisterCoreTypesToEncoder ()
9690 return & Blockchain {
97- database : database ,
98- network : network ,
99- listener : & SelectiveListener {},
91+ database : database ,
92+ network : network ,
93+ listener : & SelectiveListener {},
94+ pendingBlockFn : pendingBlockFn ,
10095 }
10196}
10297
@@ -266,24 +261,6 @@ func (b *Blockchain) TransactionByHash(hash *felt.Felt) (core.Transaction, error
266261 return transaction , b .database .View (func (txn db.Transaction ) error {
267262 var err error
268263 transaction , err = transactionByHash (txn , hash )
269-
270- // not found in the canonical blocks, try pending
271- if errors .Is (err , db .ErrKeyNotFound ) {
272- var pending * Pending
273- pending , err = pendingBlock (txn )
274- if err != nil {
275- return err
276- }
277-
278- for _ , t := range pending .Block .Transactions {
279- if hash .Equal (t .Hash ()) {
280- transaction = t
281- return nil
282- }
283- }
284- return db .ErrKeyNotFound
285- }
286-
287264 return err
288265 })
289266}
@@ -299,29 +276,6 @@ func (b *Blockchain) Receipt(hash *felt.Felt) (*core.TransactionReceipt, *felt.F
299276 return receipt , blockHash , blockNumber , b .database .View (func (txn db.Transaction ) error {
300277 var err error
301278 receipt , blockHash , blockNumber , err = receiptByHash (txn , hash )
302-
303- // not found in the canonical blocks, try pending
304- if errors .Is (err , db .ErrKeyNotFound ) {
305- var pending * Pending
306- pending , err = pendingBlock (txn )
307- if err != nil {
308- if ! errors .Is (err , ErrPendingBlockNotFound ) {
309- return err
310- }
311- return db .ErrKeyNotFound
312- }
313-
314- for i , t := range pending .Block .Transactions {
315- if hash .Equal (t .Hash ()) {
316- receipt = pending .Block .Receipts [i ]
317- blockHash = nil
318- blockNumber = 0
319- return nil
320- }
321- }
322- return db .ErrKeyNotFound
323- }
324-
325279 return err
326280 })
327281}
@@ -407,7 +361,7 @@ func (b *Blockchain) VerifyBlock(block *core.Block) error {
407361}
408362
409363func verifyBlock (txn db.Transaction , block * core.Block ) error {
410- if err := checkBlockVersion (block .ProtocolVersion ); err != nil {
364+ if err := CheckBlockVersion (block .ProtocolVersion ); err != nil {
411365 return err
412366 }
413367
@@ -865,7 +819,7 @@ func (b *Blockchain) EventFilter(from *felt.Felt, keys [][]felt.Felt) (EventFilt
865819 return nil , err
866820 }
867821
868- return newEventFilter (txn , from , keys , 0 , latest , & pending ), nil
822+ return newEventFilter (txn , from , keys , 0 , latest , b . pendingBlockFn ), nil
869823}
870824
871825// RevertHead reverts the head block
@@ -975,87 +929,3 @@ func removeTxsAndReceipts(txn db.Transaction, blockNumber, numTxs uint64) error
975929
976930 return nil
977931}
978-
979- // StorePending stores a pending block given that it is for the next height
980- func (b * Blockchain ) StorePending (p * Pending ) error {
981- err := checkBlockVersion (p .Block .ProtocolVersion )
982- if err != nil {
983- return err
984- }
985- return b .database .View (func (txn db.Transaction ) error {
986- expectedParentHash := new (felt.Felt )
987- h , err := headsHeader (txn )
988- if err != nil && ! errors .Is (err , db .ErrKeyNotFound ) {
989- return err
990- } else if err == nil {
991- expectedParentHash = h .Hash
992- }
993-
994- if ! expectedParentHash .Equal (p .Block .ParentHash ) {
995- return ErrParentDoesNotMatchHead
996- }
997-
998- if existingPending , err := pendingBlock (txn ); err == nil {
999- if existingPending .Block .TransactionCount >= p .Block .TransactionCount {
1000- // ignore the incoming pending if it has fewer transactions than the one we already have
1001- return nil
1002- }
1003- } else if ! errors .Is (err , ErrPendingBlockNotFound ) {
1004- return err
1005- }
1006-
1007- if h != nil {
1008- p .Block .Number = h .Number + 1
1009- }
1010- pending .Store (p )
1011-
1012- return nil
1013- })
1014- }
1015-
1016- func pendingBlock (txn db.Transaction ) (* Pending , error ) {
1017- p := pending .Load ()
1018- if p == nil {
1019- return nil , ErrPendingBlockNotFound
1020- }
1021-
1022- expectedParentHash := & felt .Zero
1023- if head , err := headsHeader (txn ); err == nil {
1024- expectedParentHash = head .Hash
1025- }
1026- if p .Block .ParentHash .Equal (expectedParentHash ) {
1027- return p , nil
1028- }
1029-
1030- // Since the pending block in the cache is outdated remove it
1031- pending .Store (nil )
1032-
1033- return nil , ErrPendingBlockNotFound
1034- }
1035-
1036- // Pending returns the pending block from the database
1037- func (b * Blockchain ) Pending () (* Pending , error ) {
1038- b .listener .OnRead ("Pending" )
1039- var pending * Pending
1040- return pending , b .database .View (func (txn db.Transaction ) error {
1041- var err error
1042- pending , err = pendingBlock (txn )
1043- return err
1044- })
1045- }
1046-
1047- // PendingState returns the state resulting from execution of the pending block
1048- func (b * Blockchain ) PendingState () (core.StateReader , StateCloser , error ) {
1049- b .listener .OnRead ("PendingState" )
1050- txn , err := b .database .NewTransaction (false )
1051- if err != nil {
1052- return nil , nil , err
1053- }
1054-
1055- pending , err := pendingBlock (txn )
1056- if err != nil {
1057- return nil , nil , utils .RunAndWrapOnError (txn .Discard , err )
1058- }
1059-
1060- return NewPendingState (pending .StateUpdate .StateDiff , pending .NewClasses , core .NewState (txn )), txn .Discard , nil
1061- }
0 commit comments