File tree 3 files changed +81
-5
lines changed
3 files changed +81
-5
lines changed Original file line number Diff line number Diff line change @@ -2725,8 +2725,39 @@ func (a *Array) setCallbackWithChild(i uint64, child Value) {
2725
2725
return err
2726
2726
}
2727
2727
2728
- if existingValueStorable == nil {
2729
- return NewFatalError (fmt .Errorf ("failed to reset child value in parent updater callback because previous value is nil" ))
2728
+ // Verify overwritten storable has identical value ID.
2729
+
2730
+ switch x := existingValueStorable .(type ) {
2731
+ case SlabIDStorable :
2732
+ sid := SlabID (x )
2733
+ if ! vid .equal (sid ) {
2734
+ return NewFatalError (
2735
+ fmt .Errorf (
2736
+ "failed to reset child value in parent updater callback: overwritten SlabIDStorable %s != value ID %s" ,
2737
+ sid ,
2738
+ vid ))
2739
+ }
2740
+
2741
+ case Slab :
2742
+ sid := x .SlabID ()
2743
+ if ! vid .equal (sid ) {
2744
+ return NewFatalError (
2745
+ fmt .Errorf (
2746
+ "failed to reset child value in parent updater callback: overwritten Slab ID %s != value ID %s" ,
2747
+ sid ,
2748
+ vid ))
2749
+ }
2750
+
2751
+ case nil :
2752
+ return NewFatalError (
2753
+ fmt .Errorf (
2754
+ "failed to reset child value in parent updater callback: overwritten value is nil" ))
2755
+
2756
+ default :
2757
+ return NewFatalError (
2758
+ fmt .Errorf (
2759
+ "failed to reset child value in parent updater callback: overwritten value is wrong type %T" ,
2760
+ existingValueStorable ))
2730
2761
}
2731
2762
2732
2763
return nil
Original file line number Diff line number Diff line change @@ -4523,6 +4523,8 @@ func (m *OrderedMap) setCallbackWithChild(
4523
4523
return
4524
4524
}
4525
4525
4526
+ vid := c .ValueID ()
4527
+
4526
4528
c .setParentUpdater (func () error {
4527
4529
// Set child value with parent map using same key.
4528
4530
// Set() calls c.Storable() which returns inlined or not-inlined child storable.
@@ -4531,10 +4533,40 @@ func (m *OrderedMap) setCallbackWithChild(
4531
4533
return err
4532
4534
}
4533
4535
4534
- if existingValueStorable == nil {
4535
- return NewFatalError (fmt .Errorf ("failed to reset child value in parent updater callback because previous value is nil" ))
4536
- }
4536
+ // Verify overwritten storable has identical value ID.
4537
+
4538
+ switch x := existingValueStorable .(type ) {
4539
+ case SlabIDStorable :
4540
+ sid := SlabID (x )
4541
+ if ! vid .equal (sid ) {
4542
+ return NewFatalError (
4543
+ fmt .Errorf (
4544
+ "failed to reset child value in parent updater callback: overwritten SlabIDStorable %s != value ID %s" ,
4545
+ sid ,
4546
+ vid ))
4547
+ }
4548
+
4549
+ case Slab :
4550
+ sid := x .SlabID ()
4551
+ if ! vid .equal (sid ) {
4552
+ return NewFatalError (
4553
+ fmt .Errorf (
4554
+ "failed to reset child value in parent updater callback: overwritten Slab ID %s != value ID %s" ,
4555
+ sid ,
4556
+ vid ))
4557
+ }
4558
+
4559
+ case nil :
4560
+ return NewFatalError (
4561
+ fmt .Errorf (
4562
+ "failed to reset child value in parent updater callback: overwritten value is nil" ))
4537
4563
4564
+ default :
4565
+ return NewFatalError (
4566
+ fmt .Errorf (
4567
+ "failed to reset child value in parent updater callback: overwritten value is wrong type %T" ,
4568
+ existingValueStorable ))
4569
+ }
4538
4570
return nil
4539
4571
})
4540
4572
}
Original file line number Diff line number Diff line change @@ -41,6 +41,19 @@ func slabIDToValueID(sid SlabID) ValueID {
41
41
return id
42
42
}
43
43
44
+ func (vid ValueID ) equal (sid SlabID ) bool {
45
+ return bytes .Equal (vid [:8 ], sid .address [:]) &&
46
+ bytes .Equal (vid [8 :], sid .index [:])
47
+ }
48
+
49
+ func (vid ValueID ) String () string {
50
+ return fmt .Sprintf (
51
+ "0x%x.%d" ,
52
+ binary .BigEndian .Uint64 (vid [:8 ]),
53
+ binary .BigEndian .Uint64 (vid [8 :]),
54
+ )
55
+ }
56
+
44
57
type (
45
58
Address [8 ]byte
46
59
SlabIndex [8 ]byte
You can’t perform that action at this time.
0 commit comments