Skip to content

Commit f8919ba

Browse files
committed
core,codetrie: generalize contract logic to multiple chunk sizes
1 parent a14da2a commit f8919ba

File tree

2 files changed

+70
-51
lines changed

2 files changed

+70
-51
lines changed

codetrie/contract.go

Lines changed: 67 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1515
type 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

2323
func 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

8287
type Contract struct {
8388
code []byte
84-
touchedChunks map[int]bool
89+
touchedChunks []map[int]bool
8590
}
8691

8792
func 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)

core/state_processor.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
9898

9999
defer cmFile.Close()
100100
if stats.NumContracts > 0 {
101-
if _, err := cmFile.WriteString(fmt.Sprintf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", block.NumberU64(), stats.CodeSize, stats.ProofSize, stats.RLPStats.RLPSize, stats.RLPStats.UnRLPSize, stats.RLPStats.SnappySize, stats.ProofStats.Indices, stats.ProofStats.ZeroLevels, stats.ProofStats.Hashes, stats.ProofStats.Leaves)); err != nil {
101+
rlpStats := stats.RLPStats[1]
102+
proofStats := stats.ProofStats[1]
103+
if _, err := cmFile.WriteString(fmt.Sprintf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", block.NumberU64(), stats.CodeSize, stats.ProofSizes[0], stats.ProofSizes[1], stats.ProofSizes[2], rlpStats.RLPSize, rlpStats.UnRLPSize, rlpStats.SnappySize, proofStats.Indices, proofStats.ZeroLevels, proofStats.Hashes, proofStats.Leaves)); err != nil {
102104
return nil, nil, 0, err
103105
}
104106
}

0 commit comments

Comments
 (0)