import (
log "github.com/sirupsen/logrus"
+ "golang.org/x/crypto/sha3"
"github.com/vapor/consensus"
"github.com/vapor/protocol/bc"
}
spentOutputIDs := make(map[bc.Hash]bool)
+ mainchainOutputIDs := make(map[bc.Hash]bool)
for id, e := range entries {
var ord uint64
switch e := e.(type) {
+ case *bc.CrossChainInput:
+ ord = e.Ordinal
+ mainchainOutputIDs[*e.MainchainOutputId] = true
+ if *e.WitnessDestination.Value.AssetId == *consensus.BTMAssetID {
+ tx.GasInputIDs = append(tx.GasInputIDs, id)
+ }
+
case *bc.Spend:
ord = e.Ordinal
spentOutputIDs[*e.SpentOutputId] = true
tx.GasInputIDs = append(tx.GasInputIDs, id)
}
+ case *bc.VetoInput:
+ ord = e.Ordinal
+ spentOutputIDs[*e.SpentOutputId] = true
+ if *e.WitnessDestination.Value.AssetId == *consensus.BTMAssetID {
+ tx.GasInputIDs = append(tx.GasInputIDs, id)
+ }
+
case *bc.Coinbase:
ord = 0
tx.GasInputIDs = append(tx.GasInputIDs, id)
continue
}
- if ord >= uint64(len(oldTx.Inputs)) {
- continue
+ if ord < uint64(len(oldTx.Inputs)) {
+ tx.InputIDs[ord] = id
}
- tx.InputIDs[ord] = id
}
for id := range spentOutputIDs {
tx.SpentOutputIDs = append(tx.SpentOutputIDs, id)
}
+ for id := range mainchainOutputIDs {
+ tx.MainchainOutputIDs = append(tx.MainchainOutputIDs, id)
+ }
return tx
}
}
var (
- spends []*bc.Spend
- coinbase *bc.Coinbase
+ spends []*bc.Spend
+ vetoInputs []*bc.VetoInput
+ crossIns []*bc.CrossChainInput
+ coinbase *bc.Coinbase
)
muxSources := make([]*bc.ValueSource, len(tx.Inputs))
Ref: &coinbaseID,
Value: &value,
}
+
+ case *VetoInput:
+ prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
+ src := &bc.ValueSource{
+ Ref: &inp.SourceID,
+ Value: &inp.AssetAmount,
+ Position: inp.SourcePosition,
+ }
+ prevout := bc.NewVoteOutput(src, prog, 0, inp.Vote) // ordinal doesn't matter for prevouts, only for result outputs
+ prevoutID := addEntry(prevout)
+ // create entry for VetoInput
+ vetoInput := bc.NewVetoInput(&prevoutID, uint64(i))
+ vetoInput.WitnessArguments = inp.Arguments
+ vetoVoteID := addEntry(vetoInput)
+ // setup mux
+ muxSources[i] = &bc.ValueSource{
+ Ref: &vetoVoteID,
+ Value: &inp.AssetAmount,
+ }
+ vetoInputs = append(vetoInputs, vetoInput)
+
+ case *CrossChainInput:
+ prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
+ src := &bc.ValueSource{
+ Ref: &inp.SourceID,
+ Value: &inp.AssetAmount,
+ Position: inp.SourcePosition,
+ }
+
+ prevout := bc.NewIntraChainOutput(src, prog, 0) // ordinal doesn't matter
+ mainchainOutputID := addEntry(prevout)
+
+ assetDefHash := bc.NewHash(sha3.Sum256(inp.AssetDefinition))
+ assetDef := &bc.AssetDefinition{
+ Data: &assetDefHash,
+ IssuanceProgram: &bc.Program{
+ VmVersion: inp.IssuanceVMVersion,
+ Code: inp.IssuanceProgram,
+ },
+ }
+
+ crossIn := bc.NewCrossChainInput(&mainchainOutputID, prog, uint64(i), assetDef)
+ crossIn.WitnessArguments = inp.Arguments
+ crossInID := addEntry(crossIn)
+ muxSources[i] = &bc.ValueSource{
+ Ref: &crossInID,
+ Value: &inp.AssetAmount,
+ }
+ crossIns = append(crossIns, crossIn)
}
}
spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
}
+ for _, vetoInput := range vetoInputs {
+ voteOutput := entryMap[*vetoInput.SpentOutputId].(*bc.VoteOutput)
+ vetoInput.SetDestination(&muxID, voteOutput.Source.Value, vetoInput.Ordinal)
+ }
+
+ for _, crossIn := range crossIns {
+ mainchainOutput := entryMap[*crossIn.MainchainOutputId].(*bc.IntraChainOutput)
+ crossIn.SetDestination(&muxID, mainchainOutput.Source.Value, crossIn.Ordinal)
+ }
+
if coinbase != nil {
coinbase.SetDestination(&muxID, mux.Sources[0].Value, 0)
}
case out.OutputType() == VoteOutputType:
// non-retirement vote tx
- voteOut, _ := out.TypedOutput.(*VoteTxOutput)
+ voteOut, _ := out.TypedOutput.(*VoteOutput)
prog := &bc.Program{out.VMVersion(), out.ControlProgram()}
o := bc.NewVoteOutput(src, prog, uint64(i), voteOut.Vote)
resultID = addEntry(o)