|
5 | 5 | "fmt" |
6 | 6 | "math" |
7 | 7 | "path/filepath" |
| 8 | + "strings" |
8 | 9 | "testing" |
9 | 10 | "time" |
10 | 11 |
|
@@ -3046,3 +3047,110 @@ func BenchmarkAddressEvents(b *testing.B) { |
3046 | 3047 | runBenchmarkEvents(fmt.Sprintf("%d addresses and %d transactions per address", bm.addresses, bm.eventsPerAddress), bm.addresses, bm.eventsPerAddress) |
3047 | 3048 | } |
3048 | 3049 | } |
| 3050 | + |
| 3051 | +func BenchmarkRevert(b *testing.B) { |
| 3052 | + pk1 := types.GeneratePrivateKey() |
| 3053 | + uc1 := types.StandardUnlockConditions(pk1.PublicKey()) |
| 3054 | + addr1 := uc1.UnlockHash() |
| 3055 | + addr1Policy := types.SpendPolicy{Type: types.PolicyTypeUnlockConditions(uc1)} |
| 3056 | + |
| 3057 | + n := newTestChain(b, false, func(network *consensus.Network, genesisBlock types.Block) { |
| 3058 | + network.HardforkV2.AllowHeight = 1 |
| 3059 | + network.HardforkV2.RequireHeight = 1_000_000 |
| 3060 | + genesisBlock.Transactions[0].SiacoinOutputs[0].Address = addr1 |
| 3061 | + }) |
| 3062 | + genesisTxn := n.genesis().Transactions[0] |
| 3063 | + |
| 3064 | + val := genesisTxn.SiacoinOutputs[0].Value |
| 3065 | + scID := genesisTxn.SiacoinOutputID(0) |
| 3066 | + |
| 3067 | + for i := range 20000 { |
| 3068 | + if i%100 == 0 { |
| 3069 | + b.Logf("Mined %d blocks", i) |
| 3070 | + } |
| 3071 | + |
| 3072 | + // transaction with random arbitrary data |
| 3073 | + data := make([]byte, 16) |
| 3074 | + frand.Read(data) |
| 3075 | + txn1 := types.Transaction{ |
| 3076 | + ArbitraryData: [][]byte{data}, |
| 3077 | + } |
| 3078 | + |
| 3079 | + fc := prepareContract(addr1, n.tipState().Index.Height+1) |
| 3080 | + // create file contract |
| 3081 | + txn2 := types.Transaction{ |
| 3082 | + SiacoinInputs: []types.SiacoinInput{{ |
| 3083 | + ParentID: scID, |
| 3084 | + UnlockConditions: uc1, |
| 3085 | + }}, |
| 3086 | + SiacoinOutputs: []types.SiacoinOutput{{ |
| 3087 | + Address: addr1, |
| 3088 | + Value: val.Sub(fc.Payout), |
| 3089 | + }}, |
| 3090 | + FileContracts: []types.FileContract{fc}, |
| 3091 | + } |
| 3092 | + testutil.SignTransaction(n.tipState(), pk1, &txn2) |
| 3093 | + |
| 3094 | + scID = txn2.SiacoinOutputID(0) |
| 3095 | + val = txn2.SiacoinOutputs[0].Value |
| 3096 | + |
| 3097 | + // txn3 |
| 3098 | + txn3 := types.V2Transaction{ |
| 3099 | + SiacoinInputs: []types.V2SiacoinInput{{ |
| 3100 | + // Parent: getSCE(b, n.db, scID), |
| 3101 | + Parent: types.SiacoinElement{ |
| 3102 | + ID: txn2.SiacoinOutputID(0), |
| 3103 | + StateElement: types.StateElement{ |
| 3104 | + LeafIndex: types.UnassignedLeafIndex, |
| 3105 | + }, |
| 3106 | + SiacoinOutput: txn2.SiacoinOutputs[0], |
| 3107 | + }, |
| 3108 | + SatisfiedPolicy: types.SatisfiedPolicy{Policy: addr1Policy}, |
| 3109 | + }}, |
| 3110 | + SiacoinOutputs: []types.SiacoinOutput{{ |
| 3111 | + Address: addr1, |
| 3112 | + Value: val, |
| 3113 | + }}, |
| 3114 | + } |
| 3115 | + testutil.SignV2Transaction(n.tipState(), pk1, &txn3) |
| 3116 | + |
| 3117 | + scID = txn3.SiacoinOutputID(txn3.ID(), 0) |
| 3118 | + val = txn3.SiacoinOutputs[0].Value |
| 3119 | + |
| 3120 | + block := testutil.MineV2Block(n.tipState(), []types.Transaction{txn1, txn2}, []types.V2Transaction{txn3}, types.VoidAddress) |
| 3121 | + n.applyBlock(b, block) |
| 3122 | + } |
| 3123 | + |
| 3124 | + block := n.blocks[len(n.blocks)-1] |
| 3125 | + bs := n.supplements[len(n.supplements)-1] |
| 3126 | + prevState := n.states[len(n.states)-2] |
| 3127 | + |
| 3128 | + ru := consensus.RevertBlock(prevState, block, bs) |
| 3129 | + crus := []chain.RevertUpdate{{ |
| 3130 | + RevertUpdate: ru, |
| 3131 | + Block: block, |
| 3132 | + State: prevState, |
| 3133 | + }} |
| 3134 | + |
| 3135 | + b.ResetTimer() |
| 3136 | + for range b.N { |
| 3137 | + err := n.db.transaction(func(tx *txn) error { |
| 3138 | + defer tx.Rollback() |
| 3139 | + utx := &updateTx{ |
| 3140 | + tx: tx, |
| 3141 | + } |
| 3142 | + |
| 3143 | + b.StartTimer() |
| 3144 | + err := explorer.UpdateChainState(utx, crus, nil) |
| 3145 | + b.StopTimer() |
| 3146 | + |
| 3147 | + if err != nil { |
| 3148 | + return fmt.Errorf("failed to update chain state: %w", err) |
| 3149 | + } |
| 3150 | + return nil |
| 3151 | + }) |
| 3152 | + if err != nil && !strings.Contains(err.Error(), "rolled back") { |
| 3153 | + b.Fatal(err) |
| 3154 | + } |
| 3155 | + } |
| 3156 | +} |
0 commit comments