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{}
|
issuedTxs := ids.Set{}
|
||||||
consumed := ids.Set{}
|
consumed := ids.Set{}
|
||||||
issued := false
|
issued := false
|
||||||
|
orphans := t.Consensus.Orphans()
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
inputs := tx.InputIDs()
|
inputs := tx.InputIDs()
|
||||||
overlaps := consumed.Overlaps(inputs)
|
overlaps := consumed.Overlaps(inputs)
|
||||||
|
@ -380,8 +381,10 @@ func (t *Transitive) batch(txs []snowstorm.Tx, force, empty bool) error {
|
||||||
overlaps = false
|
overlaps = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force allows for a conflict to be issued
|
if txID := tx.ID(); !overlaps && // should never allow conflicting txs in the same vertex
|
||||||
if txID := tx.ID(); !overlaps && !issuedTxs.Contains(txID) && (force || t.Consensus.IsVirtuous(tx)) && !tx.Status().Decided() {
|
!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)
|
batch = append(batch, tx)
|
||||||
issuedTxs.Add(txID)
|
issuedTxs.Add(txID)
|
||||||
consumed.Union(inputs)
|
consumed.Union(inputs)
|
||||||
|
|
|
@ -2975,3 +2975,110 @@ func TestEngineAggressivePolling(t *testing.T) {
|
||||||
t.Fatalf("should have issued one pull query")
|
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