@@ -2,6 +2,7 @@ package api
22
33import (
44 "bytes"
5+ "context"
56 "errors"
67 "net/http"
78
@@ -16,10 +17,41 @@ type getProofResp struct {
1617 Proof []hexutil.Bytes `json:"proof"`
1718}
1819
20+ type cachedTree struct {
21+ r getTreeResp
22+ t merkle.Tree
23+ }
24+
25+ func (s * Server ) getCachedTree (ctx context.Context , root common.Hash ) (cachedTree , error ) {
26+ r , ok := s .tlru .Get (root )
27+ if ok {
28+ return r , nil
29+ }
30+
31+ td , err := getTree (ctx , s .db , root .Bytes ())
32+ if err != nil {
33+ return cachedTree {}, err
34+ }
35+
36+ leaves := [][]byte {}
37+ for _ , l := range td .UnhashedLeaves {
38+ leaves = append (leaves , l [:])
39+ }
40+
41+ t := merkle .New (leaves )
42+ ct := cachedTree {
43+ r : td ,
44+ t : t ,
45+ }
46+
47+ s .tlru .Add (root , ct )
48+ return ct , nil
49+ }
50+
1951func (s * Server ) GetProof (w http.ResponseWriter , r * http.Request ) {
2052 var (
2153 ctx = r .Context ()
22- root = common .FromHex (r .URL .Query ().Get ("root" ))
54+ root = common .HexToHash (r .URL .Query ().Get ("root" ))
2355 leaf = common .FromHex (r .URL .Query ().Get ("unhashedLeaf" ))
2456 addr = common .FromHex (r .URL .Query ().Get ("address" ))
2557 )
@@ -33,7 +65,7 @@ func (s *Server) GetProof(w http.ResponseWriter, r *http.Request) {
3365 return
3466 }
3567
36- td , err := getTree ( ctx , s . db , root )
68+ ct , err := s . getCachedTree ( ctx , root )
3769 if errors .Is (err , pgx .ErrNoRows ) {
3870 s .sendJSONError (r , w , nil , http .StatusNotFound , "tree not found" )
3971 w .Header ().Set ("Cache-Control" , "public, max-age=60" )
@@ -44,22 +76,19 @@ func (s *Server) GetProof(w http.ResponseWriter, r *http.Request) {
4476 }
4577
4678 var (
47- leaves [][]byte
4879 target []byte
4980 )
5081 // check if leaf is in tree and error if not
51- for _ , l := range td .UnhashedLeaves {
82+ for _ , l := range ct . r .UnhashedLeaves {
5283 if len (target ) == 0 {
5384 if len (leaf ) > 0 {
5485 if bytes .Equal (l , leaf ) {
5586 target = l
5687 }
57- } else if bytes .Equal (leaf2Addr (l , td . Ltd , td .Packed ), addr ) {
88+ } else if bytes .Equal (leaf2Addr (l , ct . r . Ltd , ct . r .Packed ), addr ) {
5889 target = l
5990 }
6091 }
61-
62- leaves = append (leaves , l )
6392 }
6493
6594 if len (target ) == 0 {
@@ -68,8 +97,7 @@ func (s *Server) GetProof(w http.ResponseWriter, r *http.Request) {
6897 }
6998
7099 var (
71- mt = merkle .New (leaves )
72- p = mt .Proof (mt .Index (target ))
100+ p = ct .t .Proof (ct .t .Index (target ))
73101 phex = []hexutil.Bytes {}
74102 )
75103
0 commit comments