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

types: Move ID output of StateElement #199

Merged
merged 2 commits into from
Oct 29, 2024
Merged
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
46 changes: 23 additions & 23 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,14 @@ func (s State) V2TransactionWeight(txn types.V2Transaction) uint64 {
var wc writeCounter
e := types.NewEncoder(&wc)
for _, sci := range txn.SiacoinInputs {
sci.Parent.MerkleProof = nil
sci.Parent.StateElement.MerkleProof = nil
sci.EncodeTo(e)
}
for _, sco := range txn.SiacoinOutputs {
types.V2SiacoinOutput(sco).EncodeTo(e)
}
for _, sfi := range txn.SiafundInputs {
sfi.Parent.MerkleProof = nil
sfi.Parent.StateElement.MerkleProof = nil
sfi.EncodeTo(e)
}
for _, sfo := range txn.SiafundOutputs {
Expand All @@ -326,14 +326,14 @@ func (s State) V2TransactionWeight(txn types.V2Transaction) uint64 {
fc.EncodeTo(e)
}
for _, fcr := range txn.FileContractRevisions {
fcr.Parent.MerkleProof = nil
fcr.Parent.StateElement.MerkleProof = nil
fcr.EncodeTo(e)
}
for _, fcr := range txn.FileContractResolutions {
fcr.Parent.MerkleProof = nil
fcr.Parent.StateElement.MerkleProof = nil
if sp, ok := fcr.Resolution.(*types.V2StorageProof); ok {
c := *sp // don't modify original
c.ProofIndex.MerkleProof = nil
c.ProofIndex.StateElement.MerkleProof = nil
fcr.Resolution = &c
}
fcr.EncodeTo(e)
Expand Down Expand Up @@ -589,12 +589,12 @@ func (s State) AttestationSigHash(a types.Attestation) types.Hash256 {
// A MidState represents the state of the chain within a block.
type MidState struct {
base State
created map[types.Hash256]int // indices into element slices
spends map[types.Hash256]types.TransactionID
revs map[types.Hash256]*types.FileContractElement
res map[types.Hash256]bool
v2revs map[types.Hash256]*types.V2FileContractElement
v2res map[types.Hash256]types.V2FileContractResolutionType
created map[types.ElementID]int // indices into element slices
spends map[types.ElementID]types.TransactionID
revs map[types.FileContractID]*types.FileContractElement
res map[types.FileContractID]bool
v2revs map[types.FileContractID]*types.V2FileContractElement
v2res map[types.FileContractID]types.V2FileContractResolutionType
siafundPool types.Currency
foundationPrimary types.Address
foundationFailsafe types.Address
Expand All @@ -616,33 +616,33 @@ func (ms *MidState) siacoinElement(ts V1TransactionSupplement, id types.SiacoinO
}

func (ms *MidState) siafundElement(ts V1TransactionSupplement, id types.SiafundOutputID) (types.SiafundElement, bool) {
if i, ok := ms.created[types.Hash256(id)]; ok {
if i, ok := ms.created[id]; ok {
return ms.sfes[i], true
}
return ts.siafundElement(id)
}

func (ms *MidState) fileContractElement(ts V1TransactionSupplement, id types.FileContractID) (types.FileContractElement, bool) {
if rev, ok := ms.revs[types.Hash256(id)]; ok {
if rev, ok := ms.revs[id]; ok {
return *rev, true
}
if i, ok := ms.created[types.Hash256(id)]; ok {
if i, ok := ms.created[id]; ok {
return ms.fces[i], true
}
return ts.revision(id)
}

func (ms *MidState) spent(id types.Hash256) (types.TransactionID, bool) {
func (ms *MidState) spent(id types.ElementID) (types.TransactionID, bool) {
txid, ok := ms.spends[id]
return txid, ok
}

func (ms *MidState) isSpent(id types.Hash256) bool {
func (ms *MidState) isSpent(id types.ElementID) bool {
_, ok := ms.spends[id]
return ok
}

func (ms *MidState) isCreated(id types.Hash256) bool {
func (ms *MidState) isCreated(id types.ElementID) bool {
_, ok := ms.created[id]
return ok || id == ms.cie.ID
}
Expand All @@ -651,12 +651,12 @@ func (ms *MidState) isCreated(id types.Hash256) bool {
func NewMidState(s State) *MidState {
return &MidState{
base: s,
created: make(map[types.Hash256]int),
spends: make(map[types.Hash256]types.TransactionID),
revs: make(map[types.Hash256]*types.FileContractElement),
res: make(map[types.Hash256]bool),
v2revs: make(map[types.Hash256]*types.V2FileContractElement),
v2res: make(map[types.Hash256]types.V2FileContractResolutionType),
created: make(map[types.ElementID]int),
spends: make(map[types.ElementID]types.TransactionID),
revs: make(map[types.FileContractID]*types.FileContractElement),
res: make(map[types.FileContractID]bool),
v2revs: make(map[types.FileContractID]*types.V2FileContractElement),
v2res: make(map[types.FileContractID]types.V2FileContractResolutionType),
siafundPool: s.SiafundPool,
foundationPrimary: s.FoundationPrimaryAddress,
foundationFailsafe: s.FoundationFailsafeAddress,
Expand Down
110 changes: 60 additions & 50 deletions consensus/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,14 @@ func ApplyOrphan(s State, b types.Block, targetTimestamp time.Time) State {
return next
}

func dupProof(se *types.StateElement) {
se.MerkleProof = append([]types.Hash256(nil), se.MerkleProof...)
}

func (ms *MidState) addSiacoinElement(id types.SiacoinOutputID, sco types.SiacoinOutput) {
sce := types.SiacoinElement{
StateElement: types.StateElement{ID: types.Hash256(id)},
StateElement: types.StateElement{LeafIndex: types.UnassignedLeafIndex},
ID: id,
SiacoinOutput: sco,
}
ms.sces = append(ms.sces, sce)
Expand All @@ -352,14 +357,15 @@ func (ms *MidState) addImmatureSiacoinElement(id types.SiacoinOutputID, sco type
func (ms *MidState) spendSiacoinElement(sce types.SiacoinElement, txid types.TransactionID) {
ms.spends[sce.ID] = txid
if !ms.isCreated(sce.ID) {
sce.MerkleProof = append([]types.Hash256(nil), sce.MerkleProof...)
dupProof(&sce.StateElement)
ms.sces = append(ms.sces, sce)
}
}

func (ms *MidState) addSiafundElement(id types.SiafundOutputID, sfo types.SiafundOutput) {
sfe := types.SiafundElement{
StateElement: types.StateElement{ID: types.Hash256(id)},
StateElement: types.StateElement{LeafIndex: types.UnassignedLeafIndex},
ID: id,
SiafundOutput: sfo,
ClaimStart: ms.siafundPool,
}
Expand All @@ -370,14 +376,15 @@ func (ms *MidState) addSiafundElement(id types.SiafundOutputID, sfo types.Siafun
func (ms *MidState) spendSiafundElement(sfe types.SiafundElement, txid types.TransactionID) {
ms.spends[sfe.ID] = txid
if !ms.isCreated(sfe.ID) {
sfe.MerkleProof = append([]types.Hash256(nil), sfe.MerkleProof...)
dupProof(&sfe.StateElement)
ms.sfes = append(ms.sfes, sfe)
}
}

func (ms *MidState) addFileContractElement(id types.FileContractID, fc types.FileContract) {
fce := types.FileContractElement{
StateElement: types.StateElement{ID: types.Hash256(id)},
StateElement: types.StateElement{LeafIndex: types.UnassignedLeafIndex},
ID: id,
FileContract: fc,
}
ms.fces = append(ms.fces, fce)
Expand All @@ -394,10 +401,10 @@ func (ms *MidState) reviseFileContractElement(fce types.FileContractElement, rev
r.FileContract = rev
} else {
// store the original
fce.MerkleProof = append([]types.Hash256(nil), fce.MerkleProof...)
dupProof(&fce.StateElement)
ms.fces = append(ms.fces, fce)
// store the revision
fce.MerkleProof = append([]types.Hash256(nil), fce.MerkleProof...)
dupProof(&fce.StateElement)
fce.FileContract = rev
ms.revs[fce.ID] = &fce
}
Expand All @@ -407,13 +414,14 @@ func (ms *MidState) reviseFileContractElement(fce types.FileContractElement, rev
func (ms *MidState) resolveFileContractElement(fce types.FileContractElement, valid bool, txid types.TransactionID) {
ms.res[fce.ID] = valid
ms.spends[fce.ID] = txid
fce.MerkleProof = append([]types.Hash256(nil), fce.MerkleProof...)
dupProof(&fce.StateElement)
ms.fces = append(ms.fces, fce)
}

func (ms *MidState) addV2FileContractElement(id types.FileContractID, fc types.V2FileContract) {
fce := types.V2FileContractElement{
StateElement: types.StateElement{ID: types.Hash256(id)},
StateElement: types.StateElement{LeafIndex: types.UnassignedLeafIndex},
ID: id,
V2FileContract: fc,
}
ms.v2fces = append(ms.v2fces, fce)
Expand All @@ -429,10 +437,10 @@ func (ms *MidState) reviseV2FileContractElement(fce types.V2FileContractElement,
r.V2FileContract = rev
} else {
// store the original
fce.MerkleProof = append([]types.Hash256(nil), fce.MerkleProof...)
dupProof(&fce.StateElement)
ms.v2fces = append(ms.v2fces, fce)
// store the revision
fce.MerkleProof = append([]types.Hash256(nil), fce.MerkleProof...)
dupProof(&fce.StateElement)
fce.V2FileContract = rev
ms.v2revs[fce.ID] = &fce
}
Expand All @@ -442,7 +450,7 @@ func (ms *MidState) reviseV2FileContractElement(fce types.V2FileContractElement,
func (ms *MidState) resolveV2FileContractElement(fce types.V2FileContractElement, res types.V2FileContractResolutionType, txid types.TransactionID) {
ms.v2res[fce.ID] = res
ms.spends[fce.ID] = txid
fce.MerkleProof = append([]types.Hash256(nil), fce.MerkleProof...)
dupProof(&fce.StateElement)
ms.v2fces = append(ms.v2fces, fce)
}

Expand Down Expand Up @@ -521,7 +529,7 @@ func (ms *MidState) ApplyV2Transaction(txn types.V2Transaction) {
for _, sfi := range txn.SiafundInputs {
ms.spendSiafundElement(sfi.Parent, txid)
claimPortion := ms.siafundPool.Sub(sfi.Parent.ClaimStart).Div64(ms.base.SiafundCount()).Mul64(sfi.Parent.SiafundOutput.Value)
ms.addImmatureSiacoinElement(types.SiafundOutputID(sfi.Parent.ID).V2ClaimOutputID(), types.SiacoinOutput{Value: claimPortion, Address: sfi.ClaimAddress})
ms.addImmatureSiacoinElement(sfi.Parent.ID.V2ClaimOutputID(), types.SiacoinOutput{Value: claimPortion, Address: sfi.ClaimAddress})
}
for i, sfo := range txn.SiafundOutputs {
ms.addSiafundElement(txn.SiafundOutputID(txid, i), sfo)
Expand All @@ -543,20 +551,21 @@ func (ms *MidState) ApplyV2Transaction(txn types.V2Transaction) {
renter, host = r.FinalRevision.RenterOutput, r.FinalRevision.HostOutput
renter.Value = renter.Value.Sub(r.RenterRollover)
host.Value = host.Value.Sub(r.HostRollover)
ms.addV2FileContractElement(types.FileContractID(fce.ID).V2RenewalID(), r.NewContract)
ms.addV2FileContractElement(fce.ID.V2RenewalID(), r.NewContract)
case *types.V2StorageProof:
renter, host = fc.RenterOutput, fc.HostOutput
case *types.V2FileContractFinalization:
renter, host = fc.RenterOutput, fc.HostOutput
case *types.V2FileContractExpiration:
renter, host = fc.RenterOutput, fc.MissedHostOutput()
}
ms.addImmatureSiacoinElement(types.FileContractID(fce.ID).V2RenterOutputID(), renter)
ms.addImmatureSiacoinElement(types.FileContractID(fce.ID).V2HostOutputID(), host)
ms.addImmatureSiacoinElement(fce.ID.V2RenterOutputID(), renter)
ms.addImmatureSiacoinElement(fce.ID.V2HostOutputID(), host)
}
for i, a := range txn.Attestations {
ms.addAttestationElement(types.AttestationElement{
StateElement: types.StateElement{ID: txn.AttestationID(txid, i)},
StateElement: types.StateElement{LeafIndex: types.UnassignedLeafIndex},
ID: txn.AttestationID(txid, i),
Attestation: a,
})
}
Expand Down Expand Up @@ -587,12 +596,13 @@ func (ms *MidState) ApplyBlock(b types.Block, bs V1BlockSupplement) {
}
ms.resolveFileContractElement(fce, false, types.TransactionID(bid))
for i, sco := range fce.FileContract.MissedProofOutputs {
ms.addImmatureSiacoinElement(types.FileContractID(fce.ID).MissedOutputID(i), sco)
ms.addImmatureSiacoinElement(fce.ID.MissedOutputID(i), sco)
}
}

ms.cie = types.ChainIndexElement{
StateElement: types.StateElement{ID: types.Hash256(bid)},
StateElement: types.StateElement{LeafIndex: types.UnassignedLeafIndex},
ID: bid,
ChainIndex: types.ChainIndex{Height: ms.base.childHeight(), ID: bid},
}
}
Expand Down Expand Up @@ -716,7 +726,7 @@ func (au ApplyUpdate) ForEachTreeNode(fn func(row, col uint64, h types.Hash256))
// ChainIndexElement returns the chain index element for the applied block.
func (au ApplyUpdate) ChainIndexElement() types.ChainIndexElement {
cie := au.ms.cie
cie.MerkleProof = append([]types.Hash256(nil), cie.MerkleProof...)
dupProof(&cie.StateElement)
return cie
}

Expand All @@ -736,7 +746,7 @@ func ApplyBlock(s State, b types.Block, bs V1BlockSupplement, targetTimestamp ti
// compute updated and added elements
var updated, added []elementLeaf
ms.forEachAppliedElement(func(el elementLeaf) {
if ms.isCreated(el.ID) {
if el.LeafIndex == types.UnassignedLeafIndex {
added = append(added, el)
} else {
updated = append(updated, el)
Expand Down Expand Up @@ -834,10 +844,10 @@ func RevertBlock(s State, b types.Block, bs V1BlockSupplement) RevertUpdate {
// compute updated elements
var updated, added []elementLeaf
ms.forEachRevertedElement(func(el elementLeaf) {
if !ms.isCreated(el.ID) {
updated = append(updated, el)
} else {
if el.LeafIndex == types.UnassignedLeafIndex {
added = append(added, el)
} else {
updated = append(updated, el)
}
})
eru := s.Elements.revertBlock(updated, added)
Expand All @@ -847,19 +857,19 @@ func RevertBlock(s State, b types.Block, bs V1BlockSupplement) RevertUpdate {
// condensed representation of the update types for JSON marshaling
type (
applyUpdateJSON struct {
Created []types.Hash256 `json:"created"`
Spent []types.Hash256 `json:"spent"`
ValidProof []types.Hash256 `json:"validProof"`
MissedProof []types.Hash256 `json:"missedProof"`
Revisions []types.FileContractElement `json:"revisions"`
V2Revisions []types.V2FileContractElement `json:"v2Revisions"`
V2Resolutions map[types.Hash256]types.V2FileContractResolutionType `json:"v2Resolutions"`
SiacoinElements []types.SiacoinElement `json:"siacoinElements"`
SiafundElements []types.SiafundElement `json:"siafundElements"`
FileContractElements []types.FileContractElement `json:"fileContractElements"`
V2FileContractElements []types.V2FileContractElement `json:"v2FileContractElements"`
AttestationElements []types.AttestationElement `json:"attestationElements"`
ChainIndexElement types.ChainIndexElement `json:"chainIndexElement"`
Created []types.Hash256 `json:"created"`
Spent []types.Hash256 `json:"spent"`
ValidProof []types.FileContractID `json:"validProof"`
MissedProof []types.FileContractID `json:"missedProof"`
Revisions []types.FileContractElement `json:"revisions"`
V2Revisions []types.V2FileContractElement `json:"v2Revisions"`
V2Resolutions map[types.FileContractID]types.V2FileContractResolutionType `json:"v2Resolutions"`
SiacoinElements []types.SiacoinElement `json:"siacoinElements"`
SiafundElements []types.SiafundElement `json:"siafundElements"`
FileContractElements []types.FileContractElement `json:"fileContractElements"`
V2FileContractElements []types.V2FileContractElement `json:"v2FileContractElements"`
AttestationElements []types.AttestationElement `json:"attestationElements"`
ChainIndexElement types.ChainIndexElement `json:"chainIndexElement"`

UpdatedLeaves map[int][]elementLeaf `json:"updatedLeaves"`
TreeGrowth map[int][]types.Hash256 `json:"treeGrowth"`
Expand All @@ -868,19 +878,19 @@ type (
}

revertUpdateJSON struct {
Created []types.Hash256 `json:"created"`
Spent []types.Hash256 `json:"spent"`
ValidProof []types.Hash256 `json:"validProof"`
MissedProof []types.Hash256 `json:"missedProof"`
Revisions []types.FileContractElement `json:"revisions"`
V2Revisions []types.V2FileContractElement `json:"v2Revisions"`
V2Resolutions map[types.Hash256]types.V2FileContractResolutionType `json:"v2Resolutions"`
SiacoinElements []types.SiacoinElement `json:"siacoinElements"`
SiafundElements []types.SiafundElement `json:"siafundElements"`
FileContractElements []types.FileContractElement `json:"fileContractElements"`
V2FileContractElements []types.V2FileContractElement `json:"v2FileContractElements"`
AttestationElements []types.AttestationElement `json:"attestationElements"`
ChainIndexElement types.ChainIndexElement `json:"chainIndexElement"`
Created []types.Hash256 `json:"created"`
Spent []types.Hash256 `json:"spent"`
ValidProof []types.FileContractID `json:"validProof"`
MissedProof []types.FileContractID `json:"missedProof"`
Revisions []types.FileContractElement `json:"revisions"`
V2Revisions []types.V2FileContractElement `json:"v2Revisions"`
V2Resolutions map[types.FileContractID]types.V2FileContractResolutionType `json:"v2Resolutions"`
SiacoinElements []types.SiacoinElement `json:"siacoinElements"`
SiafundElements []types.SiafundElement `json:"siafundElements"`
FileContractElements []types.FileContractElement `json:"fileContractElements"`
V2FileContractElements []types.V2FileContractElement `json:"v2FileContractElements"`
AttestationElements []types.AttestationElement `json:"attestationElements"`
ChainIndexElement types.ChainIndexElement `json:"chainIndexElement"`

UpdatedLeaves map[int][]elementLeaf `json:"updatedLeaves"`
NumLeaves uint64 `json:"numLeaves"`
Expand Down
Loading