Skip to content

Commit

Permalink
support stateless proof
Browse files Browse the repository at this point in the history
revert unnecessary changes
  • Loading branch information
weiihann committed Oct 30, 2024
1 parent a5c3119 commit 546eedd
Show file tree
Hide file tree
Showing 17 changed files with 401 additions and 118 deletions.
2 changes: 1 addition & 1 deletion conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (n *InternalNode) InsertMigratedLeaves(leaves []LeafNode, curTs AccessTimes

// We first mark all children of the subtreess that we'll update in parallel,
// so the subtree updating doesn't produce a concurrent access to n.cowChild(...).
lastChildrenIdx := -1
var lastChildrenIdx = -1
for i := range leaves {
if int(leaves[i].stem[0]) != lastChildrenIdx {
lastChildrenIdx = int(leaves[i].stem[0])
Expand Down
3 changes: 2 additions & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ var (
errUnknownNodeType = errors.New("unknown node type detected")
errMissingNodeInStateless = errors.New("trying to access a node that is missing from the stateless view")
errIsPOAStub = errors.New("trying to read/write a proof of absence leaf node")
errEpochExpired = errors.New("trying to access an expired leaf node")
errExpired = errors.New("trying to access an expired leaf node")
)

const (
// Extension status
extStatusAbsentEmpty = byte(iota) // missing child node along the path
extStatusAbsentOther // path led to a node with a different stem
extStatusPresent // stem was present
extStatusExpired // stem was present but expired
)
2 changes: 1 addition & 1 deletion empty.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (Empty) Commitment() *Point {
return &id
}

func (Empty) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
func (Empty) GetProofItems(keylist, AccessTimestamp, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
return nil, nil, nil, errors.New("trying to produce a commitment for an empty subtree")
}

Expand Down
2 changes: 1 addition & 1 deletion empty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestEmptyFuncs(t *testing.T) {
t.Fatal("commitment and commit mismatch")
}

if _, _, _, err := e.GetProofItems(nil, nil); err == nil {
if _, _, _, err := e.GetProofItems(nil, 0, nil); err == nil {
t.Fatal("get proof items should error")
}

Expand Down
5 changes: 3 additions & 2 deletions encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func ParseNode(serializedNode []byte, depth byte) (VerkleNode, error) {
case singleSlotType:
return parseSingleSlotNode(serializedNode, depth)
case expiredLeafType:
return parseExpiredLeafNode(serializedNode)
return parseExpiredLeafNode(serializedNode, depth)
default:
return nil, ErrInvalidNodeEncoding
}
Expand Down Expand Up @@ -203,9 +203,10 @@ func parseSingleSlotNode(serialized []byte, depth byte) (VerkleNode, error) {
return ln, nil
}

func parseExpiredLeafNode(serialized []byte) (VerkleNode, error) {
func parseExpiredLeafNode(serialized []byte, depth byte) (VerkleNode, error) {
l := &ExpiredLeafNode{}
l.stem = serialized[leafStemOffset : leafStemOffset+StemSize]
l.setDepth(depth)
l.commitment = new(Point)
if err := l.commitment.SetBytesUncompressed(serialized[leafStemOffset+StemSize:], true); err != nil {
return nil, fmt.Errorf("setting commitment: %w", err)
Expand Down
54 changes: 36 additions & 18 deletions expired_leaf.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,58 @@ package verkle
type ExpiredLeafNode struct {
stem Stem
commitment *Point
depth byte // used for proof only, not commitment calculation
}

func NewExpiredLeafNode(stem Stem, commitment *Point) *ExpiredLeafNode {
return &ExpiredLeafNode{stem: stem, commitment: commitment}
}

func (ExpiredLeafNode) Insert([]byte, []byte, AccessTimestamp, NodeResolverFn) error {
return errEpochExpired
func (n *ExpiredLeafNode) Insert([]byte, []byte, AccessTimestamp, NodeResolverFn) error {
return errExpired
}

func (ExpiredLeafNode) Delete([]byte, AccessTimestamp, NodeResolverFn) (bool, error) {
return false, errEpochExpired
func (n *ExpiredLeafNode) Delete([]byte, AccessTimestamp, NodeResolverFn) (bool, error) {
return false, errExpired
}

func (ExpiredLeafNode) Get([]byte, AccessTimestamp, NodeResolverFn) ([]byte, error) {
return nil, errEpochExpired
func (n *ExpiredLeafNode) Get([]byte, AccessTimestamp, NodeResolverFn) ([]byte, error) {
return nil, errExpired
}

func (n ExpiredLeafNode) Commit() *Point {
func (n *ExpiredLeafNode) Commit() *Point {
if n.commitment == nil {
panic("nil commitment")
}
return n.commitment
}

func (n ExpiredLeafNode) Commitment() *Point {
func (n *ExpiredLeafNode) Commitment() *Point {
return n.commitment
}

// TODO(weiihann): prove that something was expired, for the block to be able to execute statelessly.
func (n ExpiredLeafNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
return nil, nil, nil, errEpochExpired
func (n *ExpiredLeafNode) GetProofItems(keys keylist, curTs AccessTimestamp, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
var (
pe = &ProofElements{
Vals: make([][]byte, len(keys)),
ByPath: map[string]*Point{},
}
esses []byte = nil
poass []Stem
)

for i := range keys {
pe.ByPath[string(keys[i][:n.depth])] = n.commitment
pe.Vals[i] = nil

esses = append(esses, extStatusExpired|(n.depth<<3))
poass = append(poass, n.stem)
}

return pe, esses, poass, nil
}

func (n ExpiredLeafNode) Serialize() ([]byte, error) {
func (n *ExpiredLeafNode) Serialize() ([]byte, error) {
cBytes := n.commitment.BytesUncompressedTrusted()

var buf [expiredLeafSize]byte
Expand All @@ -74,10 +91,11 @@ func (n ExpiredLeafNode) Serialize() ([]byte, error) {
return result, nil
}

func (n ExpiredLeafNode) Copy() VerkleNode {
func (n *ExpiredLeafNode) Copy() VerkleNode {
l := &ExpiredLeafNode{}
l.stem = make(Stem, len(n.stem))

l.depth = n.depth
copy(l.stem, n.stem)
if n.commitment != nil {
l.commitment = new(Point)
l.commitment.Set(n.commitment)
Expand All @@ -86,15 +104,15 @@ func (n ExpiredLeafNode) Copy() VerkleNode {
return l
}

func (n ExpiredLeafNode) toDot(string, string) string {
func (n *ExpiredLeafNode) toDot(string, string) string {
return ""
}

func (n ExpiredLeafNode) setDepth(_ byte) {
panic("should not be try to set the depth of an ExpiredLeafNode node")
func (n *ExpiredLeafNode) setDepth(d byte) {
n.depth = d
}

func (n ExpiredLeafNode) Hash() *Fr {
func (n *ExpiredLeafNode) Hash() *Fr {
var hash Fr
n.commitment.MapToScalarField(&hash)
return &hash
Expand Down
6 changes: 3 additions & 3 deletions expired_leaf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ func TestExpiredLeafBasic(t *testing.T) {
leaf := NewExpiredLeafNode(zeroKeyTest[:StemSize], &comm)

err := leaf.Insert(zeroKeyTest, zeroKeyTest, 0, nil)
if !errors.Is(err, errEpochExpired) {
if !errors.Is(err, errExpired) {
t.Fatalf("expected epoch expired error when inserting, got %v", err)
}

_, err = leaf.Delete(zeroKeyTest, 0, nil)
if !errors.Is(err, errEpochExpired) {
if !errors.Is(err, errExpired) {
t.Fatalf("expected epoch expired error when deleting, got %v", err)
}

v, err := leaf.Get(zeroKeyTest, 0, nil)
if !errors.Is(err, errEpochExpired) {
if !errors.Is(err, errExpired) {
t.Fatalf("expected epoch expired error when getting, got %v", err)
}
if v != nil {
Expand Down
30 changes: 25 additions & 5 deletions expired_tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func TestInsertSameLeafExpired(t *testing.T) {
}

err := root.Insert(oneKeyTest, testValue, 2, nil)
if !errors.Is(err, errEpochExpired) {
if !errors.Is(err, errExpired) {
t.Fatalf("expected epoch expired error when inserting, got %v", err)
}

Expand Down Expand Up @@ -138,7 +138,7 @@ func TestGetExpired(t *testing.T) {
}

val, err := root.Get(zeroKeyTest, 2, nil)
if !errors.Is(err, errEpochExpired) {
if !errors.Is(err, errExpired) {
t.Fatalf("expected epoch expired error when getting, got %v", err)
}

Expand All @@ -156,7 +156,7 @@ func TestGetExpired(t *testing.T) {
}
}

func TestDelLeafNoExpired(t *testing.T) { // skipcq: GO-R1005
func TestDelLeafNoExpired(t *testing.T) {
t.Parallel()

root := New()
Expand All @@ -174,7 +174,7 @@ func TestDelLeafNoExpired(t *testing.T) { // skipcq: GO-R1005
}
}

func TestDelLeafExpired(t *testing.T) { // skipcq: GO-R1005
func TestDelLeafExpired(t *testing.T) {
t.Parallel()

root := New()
Expand All @@ -183,7 +183,7 @@ func TestDelLeafExpired(t *testing.T) { // skipcq: GO-R1005
}

_, err := root.Delete(zeroKeyTest, 2, nil)
if !errors.Is(err, errEpochExpired) {
if !errors.Is(err, errExpired) {
t.Fatalf("expected epoch expired error when deleting, got %v", err)
}

Expand Down Expand Up @@ -221,3 +221,23 @@ func TestRootCommitExpired(t *testing.T) {
t.Fatalf("expected commitment to be %x, got %x", &init, comm)
}
}

func TestRootCommitDiffTimestamp(t *testing.T) {
t.Parallel()

root1 := New()
if err := root1.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
t.Fatalf("error inserting: %v", err)
}
comm1 := root1.Commit()

root2 := New()
if err := root2.Insert(zeroKeyTest, testValue, 2, nil); err != nil {
t.Fatalf("error inserting: %v", err)
}
comm2 := root2.Commit()

if comm1.Equal(comm2) {
t.Fatalf("expected different commitments, got %x", comm1)
}
}
2 changes: 1 addition & 1 deletion hashednode.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (HashedNode) Commitment() *Point {
panic("can not get commitment of a hash node")
}

func (HashedNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
func (HashedNode) GetProofItems(keylist, AccessTimestamp, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
return nil, nil, nil, errors.New("can not get the full path, and there is no proof of absence")
}

Expand Down
2 changes: 1 addition & 1 deletion hashednode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func TestHashedNodeFuncs(t *testing.T) {
if v != nil {
t.Fatal("non-nil get from a hashed node")
}
if _, _, _, err := e.GetProofItems(nil, nil); err == nil {
if _, _, _, err := e.GetProofItems(nil, 0, nil); err == nil {
t.Fatal("got nil error when getting proof items from a hashed node")
}
if _, err := e.Serialize(); err != errSerializeHashedNode {
Expand Down
Loading

0 comments on commit 546eedd

Please sign in to comment.