only treat Has as an implicit write within vm.Copy context

This commit is contained in:
vyzo 2021-07-03 11:02:10 +03:00
parent 39723bbe60
commit 736d6a3c19

View File

@ -5,6 +5,8 @@ import (
"context" "context"
"encoding/binary" "encoding/binary"
"errors" "errors"
"runtime/debug"
"strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -235,16 +237,21 @@ func (s *SplitStore) Has(c cid.Cid) (bool, error) {
} }
if has { if has {
// treat it as an implicit (recursive) Write, absence options -- the vm uses this check to avoid // treat it as an implicit (recursive) Write, when it is within vm.Copy context.
// duplicate writes on Copy. // -- the vm uses this check to avoid duplicate writes on Copy.
// When we have options in the API, the vm can explicitly signal that this is an implicit Write. // When we have options in the API (or something better), the vm can explicitly signal
s.trackWrite(c, true) // that this is an implicit Write.
vmCtx := s.isVMCopyContext()
if vmCtx {
s.trackWrite(c, true)
}
// also make sure the object is considered live during compaction in case we have already // also make sure the object is considered live during compaction in case we have already
// flushed pending writes and started compaction. // flushed pending writes and started compaction.
// when within vm copy context, dags will be recursively referenced.
// in case of a race with purge, this will return a track error, which we can use to // in case of a race with purge, this will return a track error, which we can use to
// signal to the vm that the object is not fully present. // signal to the vm that the object is not fully present.
trackErr := s.trackTxnRef(c, true) trackErr := s.trackTxnRef(c, vmCtx)
// if we failed to track the object and all its dependencies, then return false so as // if we failed to track the object and all its dependencies, then return false so as
// to cause the vm to copy // to cause the vm to copy
@ -648,6 +655,11 @@ func (s *SplitStore) flushPendingWrites(locked bool) {
s.debug.LogWriteMany(s.curTs, cids, epoch) s.debug.LogWriteMany(s.curTs, cids, epoch)
} }
func (s *SplitStore) isVMCopyContext() bool {
sk := string(debug.Stack())
return strings.Contains(sk, "filecoin-project/lotus/chain/vm.Copy")
}
func (s *SplitStore) trackTxnRef(c cid.Cid, implicit bool) error { func (s *SplitStore) trackTxnRef(c cid.Cid, implicit bool) error {
if s.txnProtect == nil { if s.txnProtect == nil {
// not compacting // not compacting