Skip to content

Commit

Permalink
Merge pull request #199 from SiaFoundation/element-id
Browse files Browse the repository at this point in the history
types: Move ID output of StateElement
  • Loading branch information
n8maninger authored Oct 29, 2024
2 parents c2abb81 + d7160e6 commit 18b4d43
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 114 deletions.
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

0 comments on commit 18b4d43

Please sign in to comment.