* Saves a new block or retries reward distribution for an unprocessed block. * @param {object} block Forged block returned by the ADAMANT node API * @returns {Promise }
(block)
| 120 | * @returns {Promise<void>} |
| 121 | */ |
| 122 | async parse(block) { |
| 123 | const { id, height } = block; |
| 124 | |
| 125 | // Untrusted node data: the block id is used directly in MongoDB filters, so a |
| 126 | // non-scalar id from a malformed or malicious response could become an operator |
| 127 | // query (NoSQL injection). Only a string or finite number is a safe block id. |
| 128 | if (typeof id !== 'string' && !Number.isFinite(id)) { |
| 129 | log.warn('Skipping a forged block with a missing or malformed id from the node response.'); |
| 130 | return; |
| 131 | } |
| 132 | |
| 133 | let savedBlock; |
| 134 | try { |
| 135 | savedBlock = await mongo.blocksCollection.findOne({ id }); |
| 136 | } catch (error) { |
| 137 | log.error(`Failed to parse block ${id} at height ${height}: ${error}`); |
| 138 | return; |
| 139 | } |
| 140 | |
| 141 | if (savedBlock) { |
| 142 | if (!savedBlock.processed) { |
| 143 | log.info(`Re-trying to distribute rewards for block ${id} (height ${height})…`); |
| 144 | |
| 145 | const rewardDistributor = new RewardDistributor({ |
| 146 | ...block, |
| 147 | ...savedBlock, |
| 148 | }); |
| 149 | |
| 150 | await rewardDistributor.distribute(); |
| 151 | } |
| 152 | } else { |
| 153 | log.info(`New block forged: ${id} (height ${height}).`); |
| 154 | |
| 155 | try { |
| 156 | await mongo.blocksCollection.insertOne({ |
| 157 | ...block, |
| 158 | processed: false, |
| 159 | rewardedAddresses: [], |
| 160 | }); |
| 161 | } catch (error) { |
| 162 | log.error(`Failed to parse block ${id} at height ${height}: ${error}`); |
| 163 | return; |
| 164 | } |
| 165 | |
| 166 | log.info( |
| 167 | `Forged block successfully stored: ${id} (height ${height}). Distributing rewards…`, |
| 168 | ); |
| 169 | |
| 170 | const rewardDistributor = new RewardDistributor({ |
| 171 | ...block, |
| 172 | processed: false, |
| 173 | rewardedAddresses: [], |
| 174 | }); |
| 175 | |
| 176 | await rewardDistributor.distribute(); |
| 177 | } |
| 178 | } |
| 179 | } |
no test coverage detected