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

[wip] SSZ-optimize proof (type 1) #441

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
71 changes: 35 additions & 36 deletions proof_ipa.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"errors"
"fmt"
"sort"
"unsafe"

ipa "github.com/crate-crypto/go-ipa"
"github.com/crate-crypto/go-ipa/common"
Expand Down Expand Up @@ -83,17 +82,11 @@ type Proof struct {
PostValues [][]byte
}

type SuffixStateDiff struct {
Suffix byte `json:"suffix"`
CurrentValue *[32]byte `json:"currentValue"`
NewValue *[32]byte `json:"newValue"`
}

type SuffixStateDiffs []SuffixStateDiff

type StemStateDiff struct {
Stem [StemSize]byte `json:"stem"`
SuffixDiffs SuffixStateDiffs `json:"suffixDiffs"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

OK, now makes sense. The PR description has a small mistake that you might want to fix. Delete the SuffixDiffs SuffixStateDiffs json:"suffixDiffs" line since this field is removed.

Stem [StemSize]byte `json:"stem"`
Suffixes []byte `json:"suffixes"`
Current [][]byte `json:"current"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should remember that a proof verifier must now check that []byte has length 32 which was implicit in the type before.

New [][]byte `json:"new"`
}

type StateDiff []StemStateDiff
Expand All @@ -102,16 +95,22 @@ func (sd StateDiff) Copy() StateDiff {
ret := make(StateDiff, len(sd))
for i := range sd {
copy(ret[i].Stem[:], sd[i].Stem[:])
ret[i].SuffixDiffs = make([]SuffixStateDiff, len(sd[i].SuffixDiffs))
for j := range sd[i].SuffixDiffs {
ret[i].SuffixDiffs[j].Suffix = sd[i].SuffixDiffs[j].Suffix
if sd[i].SuffixDiffs[j].CurrentValue != nil {
ret[i].SuffixDiffs[j].CurrentValue = &[32]byte{}
copy((*ret[i].SuffixDiffs[j].CurrentValue)[:], (*sd[i].SuffixDiffs[j].CurrentValue)[:])
ret[i].Suffixes = make([]byte, len(sd[i].Suffixes))
copy(ret[i].Suffixes, sd[i].Suffixes)
ret[i].Current = make([][]byte, len(sd[i].Current))
for j := range sd[i].Current {
if len(sd[i].Current[j]) == 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Remove this empty case, and only leave the else.


} else {
copy(ret[i].Current[j], sd[i].Current[j])
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think there's a bug here? We never allocated ret[i].Current[j] so it's an empty slice. The copy will copy the number of bytes being minimum between the two parameters, thus 0.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Note that in SerializeProof an append is done, which is correct since it will grow as needed compared to this copy.

}
if sd[i].SuffixDiffs[j].NewValue != nil {
ret[i].SuffixDiffs[j].NewValue = &[32]byte{}
copy((*ret[i].SuffixDiffs[j].NewValue)[:], (*sd[i].SuffixDiffs[j].NewValue)[:])
}
ret[i].New = make([][]byte, len(sd[i].New))
for j := range sd[i].New {
if len(sd[i].New[j]) == 0 {

} else {
copy(ret[i].New[j], sd[i].New[j])
}
Comment on lines +110 to 114
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ditto two comments above.

}
}
Expand Down Expand Up @@ -257,32 +256,32 @@ func SerializeProof(proof *Proof) (*VerkleProof, StateDiff, error) {
stemdiff = &statediff[len(statediff)-1]
copy(stemdiff.Stem[:], stem)
}
stemdiff.SuffixDiffs = append(stemdiff.SuffixDiffs, SuffixStateDiff{Suffix: key[StemSize]})
newsd := &stemdiff.SuffixDiffs[len(stemdiff.SuffixDiffs)-1]
stemdiff.Suffixes = append(stemdiff.Suffixes, key[StemSize])

var valueLen = len(proof.PreValues[i])
switch valueLen {
case 0:
// null value
stemdiff.Current = append(stemdiff.Current, nil)
case 32:
newsd.CurrentValue = (*[32]byte)(proof.PreValues[i])
stemdiff.Current = append(stemdiff.Current, proof.PreValues[i])
default:
var aligned [32]byte
copy(aligned[:valueLen], proof.PreValues[i])
newsd.CurrentValue = (*[32]byte)(unsafe.Pointer(&aligned[0]))
stemdiff.Current = append(stemdiff.Current, aligned[:])
}

valueLen = len(proof.PostValues[i])
switch valueLen {
case 0:
// null value
stemdiff.Current = append(stemdiff.Current, nil)
case 32:
newsd.NewValue = (*[32]byte)(proof.PostValues[i])
stemdiff.Current = append(stemdiff.Current, proof.PostValues[i])
default:
// TODO remove usage of unsafe
var aligned [32]byte
copy(aligned[:valueLen], proof.PostValues[i])
newsd.NewValue = (*[32]byte)(unsafe.Pointer(&aligned[0]))
stemdiff.Current = append(stemdiff.Current, aligned[:])
}
}

Expand Down Expand Up @@ -347,19 +346,19 @@ func DeserializeProof(vp *VerkleProof, statediff StateDiff) (*Proof, error) {

// turn statediff into keys and values
for _, stemdiff := range statediff {
for _, suffixdiff := range stemdiff.SuffixDiffs {
for i, suffix := range stemdiff.Suffixes {
var k [32]byte
copy(k[:StemSize], stemdiff.Stem[:])
k[StemSize] = suffixdiff.Suffix
k[StemSize] = suffix
keys = append(keys, k[:])
if suffixdiff.CurrentValue != nil {
prevalues = append(prevalues, suffixdiff.CurrentValue[:])
if stemdiff.Current[i] != nil {
prevalues = append(prevalues, stemdiff.Current[i])
} else {
prevalues = append(prevalues, nil)
}

if suffixdiff.NewValue != nil {
postvalues = append(postvalues, suffixdiff.NewValue[:])
if stemdiff.New != nil {
postvalues = append(postvalues, stemdiff.New[i])
} else {
postvalues = append(postvalues, nil)
}
Expand Down Expand Up @@ -528,12 +527,12 @@ func PostStateTreeFromStateDiff(preroot VerkleNode, statediff StateDiff) (Verkle
overwrites bool
)

for _, suffixdiff := range stemstatediff.SuffixDiffs {
if /* len(suffixdiff.NewValue) > 0 - this only works for a slice */ suffixdiff.NewValue != nil {
for i, suffix := range stemstatediff.Suffixes {
if /* len(suffixdiff.NewValue) > 0 - this only works for a slice */ stemstatediff.New[i] != nil {
// if this value is non-nil, it means InsertValuesAtStem should be
// called, otherwise, skip updating the tree.
overwrites = true
values[suffixdiff.Suffix] = suffixdiff.NewValue[:]
values[suffix] = stemstatediff.New[i]
}
}

Expand Down
95 changes: 23 additions & 72 deletions proof_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,92 +183,43 @@
return nil
}

// TODO use gencodec if that works
type stemStateDiffMarshaller struct {
Stem string `json:"stem"`
SuffixDiffs SuffixStateDiffs `json:"suffixDiffs"`
Stem string `json:"stem"`
Suffixes string `json:"suffixes"`
Current []string `json:"current"`
New []string `json:"new"`
}

func (ssd StemStateDiff) MarshalJSON() ([]byte, error) {
return json.Marshal(&stemStateDiffMarshaller{
Stem: HexToPrefixedString(ssd.Stem[:]),
SuffixDiffs: ssd.SuffixDiffs,
Stem: HexToPrefixedString(ssd.Stem[:]),
Suffixes: HexToPrefixedString(ssd.Suffixes),
// Current:
// TODO implement if it makes sense.
})
}

func (ssd *StemStateDiff) UnmarshalJSON(data []byte) error {
var aux stemStateDiffMarshaller
if err := json.Unmarshal(data, &aux); err != nil {
return fmt.Errorf("stemdiff unmarshal error: %w", err)
}

stem, err := PrefixedHexStringToBytes(aux.Stem)
if err != nil {
return fmt.Errorf("invalid hex string for stem: %w", err)
}
*ssd = StemStateDiff{
SuffixDiffs: aux.SuffixDiffs,
}
copy(ssd.Stem[:], stem)
// var aux stemStateDiffMarshaller
// if err := json.Unmarshal(data, &aux); err != nil {
// return fmt.Errorf("stemdiff unmarshal error: %w", err)
// }

// stem, err := PrefixedHexStringToBytes(aux.Stem)
// if err != nil {
// return fmt.Errorf("invalid hex string for stem: %w", err)
// }
// *ssd = StemStateDiff{
// SuffixDiffs: aux.SuffixDiffs,
// }
// copy(ssd.Stem[:], stem)
// TODO implement if it makes sense
return nil
}

type suffixStateDiffMarshaller struct {

Check failure on line 221 in proof_json.go

View workflow job for this annotation

GitHub Actions / lint

type `suffixStateDiffMarshaller` is unused (unused)
Suffix byte `json:"suffix"`
CurrentValue *string `json:"currentValue"`
NewValue *string `json:"newValue"`
}

func (ssd SuffixStateDiff) MarshalJSON() ([]byte, error) {
var cvstr, nvstr *string
if ssd.CurrentValue != nil {
tempstr := HexToPrefixedString(ssd.CurrentValue[:])
cvstr = &tempstr
}
if ssd.NewValue != nil {
tempstr := HexToPrefixedString(ssd.NewValue[:])
nvstr = &tempstr
}
return json.Marshal(&suffixStateDiffMarshaller{
Suffix: ssd.Suffix,
CurrentValue: cvstr,
NewValue: nvstr,
})
}

func (ssd *SuffixStateDiff) UnmarshalJSON(data []byte) error {
aux := &suffixStateDiffMarshaller{}

if err := json.Unmarshal(data, &aux); err != nil {
return fmt.Errorf("suffix diff unmarshal error: %w", err)
}

if aux.CurrentValue != nil && len(*aux.CurrentValue) != 64 && len(*aux.CurrentValue) != 0 && len(*aux.CurrentValue) != 66 {
return fmt.Errorf("invalid hex string for current value: %s", *aux.CurrentValue)
}

*ssd = SuffixStateDiff{
Suffix: aux.Suffix,
}

if aux.CurrentValue != nil && len(*aux.CurrentValue) != 0 {
currentValueBytes, err := PrefixedHexStringToBytes(*aux.CurrentValue)
if err != nil {
return fmt.Errorf("error decoding hex string for current value: %v", err)
}

ssd.CurrentValue = &[32]byte{}
copy(ssd.CurrentValue[:], currentValueBytes)
}

if aux.NewValue != nil && len(*aux.NewValue) != 0 {
newValueBytes, err := PrefixedHexStringToBytes(*aux.NewValue)
if err != nil {
return fmt.Errorf("error decoding hex string for current value: %v", err)
}

ssd.NewValue = &[32]byte{}
copy(ssd.NewValue[:], newValueBytes)
}

return nil
}
Loading
Loading