@@ -572,31 +572,39 @@ func (t accountTokens) add(id string, value uint64) {
572572
573573// diffAccountTokens will potentially modify before and after, so they should not be reused
574574// after this call.
575- // potential overflows
576- // TODO: consider changing AccountChange to a larger type than int64
577575func diffAccountTokens (before accountTokens , after accountTokens ) AccountChange {
578576 change := make (AccountChange )
579577
580578 for k , a := range after {
581579 if b , ok := before [k ]; ok {
582580 if a > b {
583- change [k ] = int64 (a - b )
581+ change [k ] = safeUint64ToInt64 (a - b )
584582 } else if b > a {
585- change [k ] = - int64 (b - a )
583+ change [k ] = - safeUint64ToInt64 (b - a )
586584 }
587585 delete (before , k )
588586 } else {
589- change [k ] = int64 (a )
587+ change [k ] = safeUint64ToInt64 (a )
590588 }
591589 }
592590
593591 for k , v := range before {
594- change [k ] = - int64 (v )
592+ change [k ] = - safeUint64ToInt64 (v )
595593 }
596594
597595 return change
598596}
599597
598+ // safeUint64ToInt64 converts a uint64 to int64, capping at math.MaxInt64 if the value
599+ // would overflow. If a value is capped, it will cause a mismatch in the token accounting
600+ // which will be logged and raise attention anyway.
601+ func safeUint64ToInt64 (v uint64 ) int64 {
602+ if v > math .MaxInt64 {
603+ return math .MaxInt64
604+ }
605+ return int64 (v )
606+ }
607+
600608type forEachCallback func (owner string , key string , value []byte ) error
601609
602610type registers interface {
0 commit comments