Implemented filtered vertex issuance

This commit is contained in:
Stephen Buttolph 2020-03-16 16:38:06 -04:00
parent 799d6dd0e1
commit 47bf310abc
3 changed files with 94 additions and 5 deletions

View File

@ -6,6 +6,7 @@ package avalanche
import (
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/snow/consensus/avalanche"
"github.com/ava-labs/gecko/snow/consensus/snowstorm"
)
type issuer struct {
@ -44,14 +45,24 @@ func (i *issuer) Update() {
vtxID := i.vtx.ID()
i.t.pending.Remove(vtxID)
for _, tx := range i.vtx.Txs() {
txs := i.vtx.Txs()
validTxs := []snowstorm.Tx{}
for _, tx := range txs {
if err := tx.Verify(); err != nil {
i.t.Config.Context.Log.Debug("Transaction failed verification due to %s, dropping vertex", err)
i.t.vtxBlocked.Abandon(vtxID)
return
i.t.Config.Context.Log.Debug("Transaction %s failed verification due to %s", tx.ID(), err)
} else {
validTxs = append(validTxs, tx)
}
}
if len(validTxs) != len(txs) {
i.t.Config.Context.Log.Debug("Abandoning %s due to failed transaction verification", vtxID)
i.t.batch(validTxs, false /*=force*/, false /*=empty*/)
i.t.vtxBlocked.Abandon(vtxID)
return
}
i.t.Config.Context.Log.Verbo("Adding vertex to consensus:\n%s", i.vtx)
i.t.Consensus.Add(i.vtx)

View File

@ -309,7 +309,7 @@ func (t *Transitive) batch(txs []snowstorm.Tx, force, empty bool) {
}
// 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 && !issuedTxs.Contains(txID) && (force || t.Consensus.IsVirtuous(tx)) && !tx.Status().Decided() {
batch = append(batch, tx)
issuedTxs.Add(txID)
consumed.Union(inputs)

View File

@ -2469,3 +2469,81 @@ func TestEngineUndeclaredDependencyDeadlock(t *testing.T) {
t.Fatalf("should have accepted the vertex due to transitive voting")
}
}
func TestEnginePartiallyValidVertex(t *testing.T) {
config := DefaultConfig()
vdr := validators.GenerateRandomValidator(1)
vals := validators.NewSet()
config.Validators = vals
vals.Add(vdr)
st := &stateTest{t: t}
config.State = st
gVtx := &Vtx{
id: GenerateID(),
status: choices.Accepted,
}
vts := []avalanche.Vertex{gVtx}
utxos := []ids.ID{GenerateID(), GenerateID()}
tx0 := &TestTx{
TestTx: snowstorm.TestTx{
Identifier: GenerateID(),
Stat: choices.Processing,
},
}
tx0.Ins.Add(utxos[0])
tx1 := &TestTx{
TestTx: snowstorm.TestTx{
Identifier: GenerateID(),
Stat: choices.Processing,
Validity: errors.New(""),
},
}
tx1.Ins.Add(utxos[1])
vtx := &Vtx{
parents: vts,
id: GenerateID(),
txs: []snowstorm.Tx{tx0, tx1},
height: 1,
status: choices.Processing,
}
te := &Transitive{}
te.Initialize(config)
te.finishBootstrapping()
expectedVtxID := GenerateID()
st.buildVertex = func(_ ids.Set, txs []snowstorm.Tx) (avalanche.Vertex, error) {
consumers := []snowstorm.Tx{}
for _, tx := range txs {
consumers = append(consumers, tx)
}
return &Vtx{
parents: vts,
id: expectedVtxID,
txs: consumers,
status: choices.Processing,
bytes: []byte{1},
}, nil
}
sender := &common.SenderTest{}
sender.T = t
te.Config.Sender = sender
sender.PushQueryF = func(_ ids.ShortSet, _ uint32, vtxID ids.ID, _ []byte) {
if !expectedVtxID.Equals(vtxID) {
t.Fatalf("wrong vertex queried")
}
}
te.insert(vtx)
}