Remove tip block on reorg */
| 138 | |
| 139 | /* Remove tip block on reorg */ |
| 140 | void bwatch_remove_tip(struct command *cmd, struct bwatch *bwatch) |
| 141 | { |
| 142 | const struct block_record_wire *newtip; |
| 143 | size_t count = tal_count(bwatch->block_history); |
| 144 | |
| 145 | if (count == 0) { |
| 146 | plugin_log(bwatch->plugin, LOG_BROKEN, |
| 147 | "remove_tip called with no block history!"); |
| 148 | return; |
| 149 | } |
| 150 | |
| 151 | plugin_log(bwatch->plugin, LOG_DBG, "Removing stale block %u: %s", |
| 152 | bwatch->current_height, |
| 153 | fmt_bitcoin_blkid(tmpctx, &bwatch->current_blockhash)); |
| 154 | |
| 155 | /* Notify owners of any watch affected by losing this block before we |
| 156 | * tear it down, so they can roll back in the same order things happened. */ |
| 157 | bwatch_notify_reorg_watches(cmd, bwatch, bwatch->current_height); |
| 158 | |
| 159 | /* Delete block from datastore */ |
| 160 | bwatch_delete_block_from_datastore(cmd, bwatch->current_height); |
| 161 | |
| 162 | /* Remove last block from history */ |
| 163 | tal_resize(&bwatch->block_history, count - 1); |
| 164 | |
| 165 | /* Move tip back one */ |
| 166 | newtip = bwatch_last_block(bwatch); |
| 167 | if (newtip) { |
| 168 | assert(newtip->height == bwatch->current_height - 1); |
| 169 | bwatch->current_height = newtip->height; |
| 170 | bwatch->current_blockhash = newtip->hash; |
| 171 | |
| 172 | /* Tell watchman the tip rolled back so it persists the new height+hash. |
| 173 | * If we crash before the ack, watchman's stale height > bwatch's height |
| 174 | * on restart, which naturally retriggers the rollback via getwatchmanheight. */ |
| 175 | bwatch_send_revert_block_processed(cmd, bwatch->current_height, |
| 176 | &bwatch->current_blockhash); |
| 177 | } else { |
| 178 | /* History exhausted: we've rolled back past everything we stored. |
| 179 | * Set current_height to 0 so getwatchmanheight_done can reset it to |
| 180 | * watchman_height. Don't notify watchman — it already knows its own |
| 181 | * height and we're about to resume from there via sequential polling. */ |
| 182 | bwatch->current_height = 0; |
| 183 | memset(&bwatch->current_blockhash, 0, sizeof(bwatch->current_blockhash)); |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /* Process or initialize from a block. */ |
| 188 | static struct command_result *handle_block(struct command *cmd, |
no test coverage detected