@@ -184,6 +184,45 @@ func TestSTM(t *testing.T) {
184184 }
185185}
186186
187+ // TestSTMHighContentionStress runs high-contention blocks many times.
188+ // With count=1, TestSTM passes because the bug is probabilistic.
189+ // With 200 iterations, the scheduler non-determinism triggers reliably.
190+ func TestSTMHighContentionStress (t * testing.T ) {
191+ stores := map [storetypes.StoreKey ]int {StoreKeyAuth : 0 , StoreKeyBank : 1 }
192+ testCases := []struct {
193+ name string
194+ blk * MockBlock
195+ executors int
196+ }{
197+ {"worstCaseBlock(100),5" , worstCaseBlock (100 ), 5 },
198+ {"testBlock(100,3),10" , testBlock (100 , 3 ), 10 },
199+ }
200+
201+ for _ , tc := range testCases {
202+ t .Run (tc .name , func (t * testing.T ) {
203+ for i := 0 ; i < 200 ; i ++ {
204+ storage := NewMultiMemDB (stores )
205+ require .NoError (t ,
206+ ExecuteBlock (context .Background (), tc .blk .Size (), stores , storage , tc .executors , func (txn TxnIndex , store MultiStore ) {
207+ tc .blk .ExecuteTx (txn , store , nil )
208+ }),
209+ )
210+ for _ , err := range tc .blk .Results {
211+ require .NoError (t , err )
212+ }
213+
214+ crossCheck := NewMultiMemDB (stores )
215+ runSequential (crossCheck , tc .blk )
216+
217+ for store := range stores {
218+ require .True (t , StoreEqual (crossCheck .GetKVStore (store ), storage .GetKVStore (store )),
219+ "iteration %d: parallel != sequential for store %s" , i , store .Name ())
220+ }
221+ }
222+ })
223+ }
224+ }
225+
187226func StoreEqual (a , b storetypes.KVStore ) bool {
188227 // compare with iterators
189228 iter1 := a .Iterator (nil , nil )
0 commit comments