A very experimental PLC implementation which uses BFT consensus for decentralization
19
fork

Configure Feed

Select the types of activity you want to include in your feed.

Increase CommitToChallengeMinRange for safety, and avoid presenting an internal error when receiving junk proofs

gbl08ma e3a780ff e2cb5f8f

+35 -25
+19 -11
abciapp/block_challenge.go
··· 4 4 "bytes" 5 5 "context" 6 6 "embed" 7 + "errors" 7 8 "math/big" 8 9 "time" 9 10 ··· 199 200 return buf.Bytes(), nil 200 201 } 201 202 202 - func (c *blockChallengeCoordinator) verifyBlockChallengeProof(height int64, validatorAddress []byte, proofBytes []byte) (bool, error) { 203 + var bn254IDScalarField = bn254.ID.ScalarField() 204 + 205 + var errInvalidBlockChallengeProof = errors.New("invalid block challenge proof") 206 + 207 + func (c *blockChallengeCoordinator) verifyBlockChallengeProof(height int64, validatorAddress []byte, proofBytes []byte) error { 203 208 // timestamp shouldn't matter for this 204 209 // it is however important that we read the tree exactly as it was on the height prior to the one where the proof was supposedly generated 205 210 // this is because operations can change over time (nullification) and also the returned data for the highest operation indexes will be different 206 211 tx, err := c.txFactory.ReadHeight(time.Time{}, height-1) 207 212 if err != nil { 208 - return false, stacktrace.Propagate(err) 213 + return stacktrace.Propagate(err) 209 214 } 210 215 211 216 sharedPart, err := c.fetchOrBuildBlockChallengeCircuitAssignmentShared(tx, height) 212 217 if err != nil { 213 - return false, stacktrace.Propagate(err) 218 + return stacktrace.Propagate(err) 214 219 } 215 220 216 221 assignment := buildBlockChallengeCircuitAssignmentFull(sharedPart, validatorAddress) 217 222 218 - witness, err := frontend.NewWitness(assignment, bn254.ID.ScalarField()) 223 + witness, err := frontend.NewWitness(assignment, bn254IDScalarField) 219 224 if err != nil { 220 - return false, stacktrace.Propagate(err) 225 + return stacktrace.Propagate(err) 221 226 } 222 227 223 228 publicWitness, err := witness.Public() 224 229 if err != nil { 225 - return false, stacktrace.Propagate(err) 230 + return stacktrace.Propagate(err) 226 231 } 227 232 228 233 proof := groth16.NewProof(bn254.ID) 229 234 230 235 _, err = proof.ReadFrom(bytes.NewBuffer(proofBytes)) 231 236 if err != nil { 232 - return false, stacktrace.Propagate(err) 237 + return stacktrace.Propagate(errors.Join(errInvalidBlockChallengeProof, err)) 233 238 } 234 239 235 240 err = groth16.Verify(proof, blockChallengeVerifyingKey, publicWitness) 236 - return err == nil, nil 241 + if err != nil { 242 + return stacktrace.Propagate(errors.Join(errInvalidBlockChallengeProof, err)) 243 + } 244 + return nil 237 245 } 238 246 239 247 func (c *blockChallengeCoordinator) buildPrivateChallengeWitnessForHeight(tx transaction.Read, height int64) (witness.Witness, error) { ··· 244 252 245 253 assignment := buildBlockChallengeCircuitAssignmentFull(sharedPart, c.validatorAddress) 246 254 247 - witness, err := frontend.NewWitness(assignment, bn254.ID.ScalarField()) 255 + witness, err := frontend.NewWitness(assignment, bn254IDScalarField) 248 256 return witness, stacktrace.Propagate(err) 249 257 } 250 258 ··· 258 266 return nil, nil, stacktrace.Propagate(err) 259 267 } 260 268 lastCommitHash := blockHeader.LastCommitHash 261 - lastCommitHashBigInt := big.NewInt(0).SetBytes(lastCommitHash) 269 + lastCommitHashBigInt := new(big.Int).SetBytes(lastCommitHash) 262 270 263 271 highestOp, err := tx.CountOperations() 264 272 if err != nil { ··· 269 277 operationData := make([]byte, initialOpDataLen) 270 278 operationDataCursor := 0 271 279 if highestOp > 0 { 272 - startOpIdxBigInt := big.NewInt(0).Mod(lastCommitHashBigInt, big.NewInt(0).SetUint64(highestOp-1)) 280 + startOpIdxBigInt := new(big.Int).Mod(lastCommitHashBigInt, new(big.Int).SetUint64(highestOp-1)) 273 281 startOpIdx := startOpIdxBigInt.Uint64() 274 282 // the starting operation sequence is startOpIdx+1 275 283 // because operations sequences start at 1 but the result of the modulus is (0, n(
+7 -3
abciapp/execution.go
··· 251 251 }, nil 252 252 } 253 253 254 - proofOK, err := d.blockChallengeCoordinator.verifyBlockChallengeProof(req.Height, req.ValidatorAddress, req.VoteExtension) 255 - if err != nil { 254 + err := d.blockChallengeCoordinator.verifyBlockChallengeProof(req.Height, req.ValidatorAddress, req.VoteExtension) 255 + if errors.Is(err, errInvalidBlockChallengeProof) { 256 + return &abcitypes.ResponseVerifyVoteExtension{ 257 + Status: abcitypes.ResponseVerifyVoteExtension_REJECT, 258 + }, nil 259 + } else if err != nil { 256 260 return nil, stacktrace.Propagate(err) 257 261 } 258 262 259 263 return &abcitypes.ResponseVerifyVoteExtension{ 260 - Status: lo.Ternary(proofOK, abcitypes.ResponseVerifyVoteExtension_ACCEPT, abcitypes.ResponseVerifyVoteExtension_REJECT), 264 + Status: abcitypes.ResponseVerifyVoteExtension_ACCEPT, 261 265 }, nil 262 266 } 263 267
+9 -11
abciapp/tx_challenge.go
··· 17 17 var TransactionActionCommitToChallenge = registerTransactionAction[CommitToChallengeArguments]("CommitToChallenge", processCommitToChallengeTx) 18 18 19 19 const CommitToChallengeMaxAgeInBlocks = 3 20 - const CommitToChallengeMinRange = 1000 20 + const CommitToChallengeMinRange = 1950 21 21 const CommitToChallengeMaxRange = 5000 22 22 const CommitToChallengeTargetInterval = 2000 23 23 ··· 159 159 }, nil 160 160 } 161 161 162 - blockProofValid, err := deps.blockChallengeCoordinator.verifyBlockChallengeProof(int64(proofHeight), validatorPubKey.Address(), existenceProof.Value) 163 - if err != nil { 164 - return nil, stacktrace.Propagate(err) 165 - } 166 - if !blockProofValid { 162 + err = deps.blockChallengeCoordinator.verifyBlockChallengeProof(int64(proofHeight), validatorPubKey.Address(), existenceProof.Value) 163 + if errors.Is(err, errInvalidBlockChallengeProof) { 167 164 return &processResult{ 168 165 Code: 4211, 169 166 Log: "invalid proof", 170 167 }, nil 168 + } else if err != nil { 169 + return nil, stacktrace.Propagate(err) 171 170 } 172 171 173 172 if !ics23.VerifyMembership(ics23.IavlSpec, tx.Arguments.Root, proof, existenceProof.Key, existenceProof.Value) { ··· 298 297 }, nil 299 298 } 300 299 301 - blockProofValid, err := deps.blockChallengeCoordinator.verifyBlockChallengeProof(int64(proofHeight), pubKey.Address(), existenceProof.Value) 302 - if err != nil { 303 - return nil, stacktrace.Propagate(err) 304 - } 305 - if !blockProofValid { 300 + err = deps.blockChallengeCoordinator.verifyBlockChallengeProof(int64(proofHeight), pubKey.Address(), existenceProof.Value) 301 + if errors.Is(err, errInvalidBlockChallengeProof) { 306 302 return &processResult{ 307 303 Code: 4307, 308 304 Log: "invalid proof", 309 305 }, nil 306 + } else if err != nil { 307 + return nil, stacktrace.Propagate(err) 310 308 } 311 309 312 310 if !ics23.VerifyMembership(ics23.IavlSpec, committedTreeRoot, proof, existenceProof.Key, existenceProof.Value) {