mirror of https://github.com/poanetwork/gecko.git
Require for reissued transactions to be orphans
This commit is contained in:
parent
218ff1136c
commit
07656c7c23
|
@ -369,6 +369,7 @@ func (t *Transitive) batch(txs []snowstorm.Tx, force, empty bool) error {
|
|||
issuedTxs := ids.Set{}
|
||||
consumed := ids.Set{}
|
||||
issued := false
|
||||
orphans := t.Consensus.Orphans()
|
||||
for _, tx := range txs {
|
||||
inputs := tx.InputIDs()
|
||||
overlaps := consumed.Overlaps(inputs)
|
||||
|
@ -380,8 +381,10 @@ func (t *Transitive) batch(txs []snowstorm.Tx, force, empty bool) error {
|
|||
overlaps = false
|
||||
}
|
||||
|
||||
// Force allows for a conflict to be issued
|
||||
if txID := tx.ID(); !overlaps && !issuedTxs.Contains(txID) && (force || t.Consensus.IsVirtuous(tx)) && !tx.Status().Decided() {
|
||||
if txID := tx.ID(); !overlaps && // should never allow conflicting txs in the same vertex
|
||||
!issuedTxs.Contains(txID) && // shouldn't issue duplicated transactions to the same vertex
|
||||
(force || t.Consensus.IsVirtuous(tx)) && // force allows for a conflict to be issued
|
||||
(!t.Consensus.TxIssued(tx) || orphans.Contains(txID)) { // should only reissued orphaned txs
|
||||
batch = append(batch, tx)
|
||||
issuedTxs.Add(txID)
|
||||
consumed.Union(inputs)
|
||||
|
|
|
@ -2975,3 +2975,110 @@ func TestEngineAggressivePolling(t *testing.T) {
|
|||
t.Fatalf("should have issued one pull query")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEngineDuplicatedIssuance(t *testing.T) {
|
||||
config := DefaultConfig()
|
||||
config.Params.BatchSize = 1
|
||||
config.Params.BetaVirtuous = 5
|
||||
config.Params.BetaRogue = 5
|
||||
|
||||
sender := &common.SenderTest{}
|
||||
sender.T = t
|
||||
config.Sender = sender
|
||||
|
||||
sender.Default(true)
|
||||
sender.CantGetAcceptedFrontier = false
|
||||
|
||||
vdr := validators.GenerateRandomValidator(1)
|
||||
|
||||
vals := validators.NewSet()
|
||||
config.Validators = vals
|
||||
|
||||
vals.Add(vdr)
|
||||
|
||||
st := &stateTest{t: t}
|
||||
config.State = st
|
||||
|
||||
st.Default(true)
|
||||
|
||||
vm := &VMTest{}
|
||||
vm.T = t
|
||||
config.VM = vm
|
||||
|
||||
vm.Default(true)
|
||||
|
||||
gVtx := &Vtx{
|
||||
id: GenerateID(),
|
||||
status: choices.Accepted,
|
||||
}
|
||||
mVtx := &Vtx{
|
||||
id: GenerateID(),
|
||||
status: choices.Accepted,
|
||||
}
|
||||
|
||||
gTx := &TestTx{
|
||||
TestTx: snowstorm.TestTx{
|
||||
Identifier: GenerateID(),
|
||||
Stat: choices.Accepted,
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []ids.ID{GenerateID(), GenerateID()}
|
||||
|
||||
tx := &TestTx{
|
||||
TestTx: snowstorm.TestTx{
|
||||
Identifier: GenerateID(),
|
||||
Deps: []snowstorm.Tx{gTx},
|
||||
Stat: choices.Processing,
|
||||
},
|
||||
}
|
||||
tx.Ins.Add(utxos[0])
|
||||
|
||||
st.edge = func() []ids.ID { return []ids.ID{gVtx.ID(), mVtx.ID()} }
|
||||
st.getVertex = func(id ids.ID) (avalanche.Vertex, error) {
|
||||
switch {
|
||||
case id.Equals(gVtx.ID()):
|
||||
return gVtx, nil
|
||||
case id.Equals(mVtx.ID()):
|
||||
return mVtx, nil
|
||||
}
|
||||
t.Fatalf("Unknown vertex")
|
||||
panic("Should have errored")
|
||||
}
|
||||
|
||||
te := &Transitive{}
|
||||
te.Initialize(config)
|
||||
te.finishBootstrapping()
|
||||
|
||||
lastVtx := new(Vtx)
|
||||
st.buildVertex = func(_ ids.Set, txs []snowstorm.Tx) (avalanche.Vertex, error) {
|
||||
consumers := []snowstorm.Tx{}
|
||||
for _, tx := range txs {
|
||||
consumers = append(consumers, tx)
|
||||
}
|
||||
lastVtx = &Vtx{
|
||||
parents: []avalanche.Vertex{gVtx, mVtx},
|
||||
id: GenerateID(),
|
||||
txs: consumers,
|
||||
status: choices.Processing,
|
||||
bytes: []byte{1},
|
||||
}
|
||||
return lastVtx, nil
|
||||
}
|
||||
|
||||
sender.CantPushQuery = false
|
||||
|
||||
vm.PendingTxsF = func() []snowstorm.Tx { return []snowstorm.Tx{tx} }
|
||||
te.Notify(common.PendingTxs)
|
||||
|
||||
if len(lastVtx.txs) != 1 || !lastVtx.txs[0].ID().Equals(tx.ID()) {
|
||||
t.Fatalf("Should have issued txs differently")
|
||||
}
|
||||
|
||||
st.buildVertex = func(ids.Set, []snowstorm.Tx) (avalanche.Vertex, error) {
|
||||
t.Fatalf("shouldn't have attempted to issue a duplicated tx")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
te.Notify(common.PendingTxs)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue