@@ -10,20 +10,21 @@ import (
1010 "github.com/ethereum/go-ethereum/common"
1111)
1212
13- const CHUNK_SIZE = 32
13+ var CHUNK_SIZES = [ ... ] int { 24 , 32 , 40 }
1414
1515type CMStats struct {
1616 NumContracts int
17- ProofSize int
17+ ProofSizes [] int
1818 CodeSize int
19- ProofStats * ssz.ProofStats
20- RLPStats * ssz.RLPStats
19+ ProofStats [] * ssz.ProofStats
20+ RLPStats [] * ssz.RLPStats
2121}
2222
2323func NewCMStats () * CMStats {
2424 return & CMStats {
25- ProofStats : & ssz.ProofStats {},
26- RLPStats : & ssz.RLPStats {},
25+ ProofSizes : make ([]int , len (CHUNK_SIZES )),
26+ ProofStats : make ([]* ssz.ProofStats , len (CHUNK_SIZES )),
27+ RLPStats : make ([]* ssz.RLPStats , len (CHUNK_SIZES )),
2728 }
2829}
2930
@@ -59,33 +60,40 @@ func (b *ContractBag) Stats() (*CMStats, error) {
5960 stats .NumContracts = len (b .contracts )
6061 for _ , c := range b .contracts {
6162 stats .CodeSize += c .CodeSize ()
62- rawProof , err := c .Prove ()
63+ rawProofs , err := c .Prove ()
6364 if err != nil {
6465 return nil , err
6566 }
66- p := ssz .NewMultiproof (rawProof )
67- cp := ssz .NewCompressedMultiproof (rawProof .Compress ())
68-
69- ps := cp .ProofStats ()
70- stats .ProofStats .Add (ps )
71-
72- rs , err := ssz .NewRLPStats (p , cp )
73- if err != nil {
74- return nil , err
67+ for i , rawProof := range rawProofs {
68+ p := ssz .NewMultiproof (rawProof )
69+ cp := ssz .NewCompressedMultiproof (rawProof .Compress ())
70+
71+ ps := cp .ProofStats ()
72+ stats .ProofStats [i ].Add (ps )
73+
74+ rs , err := ssz .NewRLPStats (p , cp )
75+ if err != nil {
76+ return nil , err
77+ }
78+ stats .RLPStats [i ].Add (rs )
7579 }
76- stats .RLPStats .Add (rs )
7780 }
78- stats .ProofSize = stats .ProofStats .Sum ()
81+ for i := 0 ; i < len (stats .ProofSizes ); i ++ {
82+ stats .ProofSizes [i ] = stats .ProofStats [i ].Sum ()
83+ }
7984 return stats , nil
8085}
8186
8287type Contract struct {
8388 code []byte
84- touchedChunks map [int ]bool
89+ touchedChunks [] map [int ]bool
8590}
8691
8792func NewContract (code []byte ) * Contract {
88- touchedChunks := make (map [int ]bool )
93+ touchedChunks := make ([]map [int ]bool , len (CHUNK_SIZES ))
94+ for i := 0 ; i < len (touchedChunks ); i ++ {
95+ touchedChunks [i ] = make (map [int ]bool )
96+ }
8997 return & Contract {code : code , touchedChunks : touchedChunks }
9098}
9199
@@ -94,8 +102,10 @@ func (c *Contract) TouchPC(pc int) error {
94102 return errors .New ("PC to touch exceeds bytecode length" )
95103 }
96104
97- cid := pc / CHUNK_SIZE
98- c .touchedChunks [cid ] = true
105+ for i , s := range CHUNK_SIZES {
106+ cid := pc / s
107+ c.touchedChunks [i ][cid ] = true
108+ }
99109
100110 return nil
101111}
@@ -108,10 +118,12 @@ func (c *Contract) TouchRange(from, to int) error {
108118 return errors .New ("PC to touch exceeds bytecode length" )
109119 }
110120
111- fcid := from / CHUNK_SIZE
112- tcid := to / CHUNK_SIZE
113- for i := fcid ; i < tcid + 1 ; i ++ {
114- c .touchedChunks [i ] = true
121+ for i , s := range CHUNK_SIZES {
122+ fcid := from / s
123+ tcid := to / s
124+ for j := fcid ; j < tcid + 1 ; j ++ {
125+ c.touchedChunks [i ][j ] = true
126+ }
115127 }
116128
117129 return nil
@@ -121,36 +133,41 @@ func (c *Contract) CodeSize() int {
121133 return len (c .code )
122134}
123135
124- func (c * Contract ) Prove () (* sszlib.Multiproof , error ) {
125- tree , err := GetSSZTree (c .code , CHUNK_SIZE )
126- if err != nil {
127- return nil , err
128- }
136+ func (c * Contract ) Prove () ([]* sszlib.Multiproof , error ) {
137+ proofs := make ([]* sszlib.Multiproof , len (CHUNK_SIZES ))
138+ for i , s := range CHUNK_SIZES {
139+ tree , err := GetSSZTree (c .code , uint (s ))
140+ if err != nil {
141+ return nil , err
142+ }
129143
130- // ChunksLen and metadata fields
131- mdIndices := []int {7 , 8 , 9 , 10 }
132-
133- touchedChunks := c .sortedTouchedChunks ()
134- chunkIndices := make ([]int , 0 , len (touchedChunks )* 2 )
135- for k := range touchedChunks {
136- // 6144 is global index for first chunk's node
137- // Each chunk node has two children: FIO, code
138- chunkIdx := 6144 + k
139- chunkIndices = append (chunkIndices , chunkIdx * 2 )
140- chunkIndices = append (chunkIndices , chunkIdx * 2 + 1 )
141- }
144+ // ChunksLen and metadata fields
145+ mdIndices := []int {7 , 8 , 9 , 10 }
146+
147+ touchedChunks := c .sortedTouchedChunks (i )
148+ chunkIndices := make ([]int , 0 , len (touchedChunks )* 2 )
149+ for k := range touchedChunks {
150+ // 6144 is global index for first chunk's node
151+ // Each chunk node has two children: FIO, code
152+ chunkIdx := 6144 + k
153+ chunkIndices = append (chunkIndices , chunkIdx * 2 )
154+ chunkIndices = append (chunkIndices , chunkIdx * 2 + 1 )
155+ }
156+
157+ p , err := tree .ProveMulti (append (mdIndices , chunkIndices ... ))
158+ if err != nil {
159+ return nil , err
160+ }
142161
143- p , err := tree .ProveMulti (append (mdIndices , chunkIndices ... ))
144- if err != nil {
145- return nil , err
162+ proofs [i ] = p
146163 }
147164
148- return p , nil
165+ return proofs , nil
149166}
150167
151- func (c * Contract ) sortedTouchedChunks () []int {
152- touched := make ([]int , 0 , len (c .touchedChunks ))
153- for k := range c .touchedChunks {
168+ func (c * Contract ) sortedTouchedChunks (sizeIndex int ) []int {
169+ touched := make ([]int , 0 , len (c .touchedChunks [ sizeIndex ] ))
170+ for k := range c .touchedChunks [ sizeIndex ] {
154171 touched = append (touched , k )
155172 }
156173 sort .Ints (touched )
0 commit comments