Open jexus6 opened 2 years ago
It is because of couchDB max_document_size https://docs.couchdb.org/en/stable/whatsnew/3.0.html To bring your channel back to life try to adjust the couchDB max_document_size Not sure why this is not handled properly by the peer. It shouldn't be possible to bring the channel down by just pushing a transaction with a data volume higher than what couchDB can accept. For example to reproduce you can just push a > 8MB doc to a PDC in one trx and you get your peer(s) down on that channel. I think the peer just has to reject the transaction endorsement instead of reaching a point of crashing to process the channel. It is also a good idea to document that so we do better design of high-data volume applications. @denyeart , @yacovm ... Hope you may help with that. Would be great to get some insights from the maintainers.
@TsvetanG It can't be checked at endorsement time because the endorsing peer has no way of knowing the configuration of max_document_size in every other peer's CouchDB.
You can resolve the problem on the peer by increasing CouchDB max_document_size and then restarting peer. Upon restart the block's state database updates will be re-attempted and will succeed given the higher max_document_size.
Unfortunately the default for max_document_size changed from 4GB to 8MB in CouchDB 3.0. This was mentioned in the Fabric release notes when CouchDB 3.0 support was added, but I agree it should go in Fabric docs as well, I've opened PR https://github.com/hyperledger/fabric/pull/4095
See doc update: https://hyperledger-fabric.readthedocs.io/en/latest/couchdb_as_state_database.html#couchdb-container-configuration
@denyeart : Thanks a lot for the update. Yes, it is unknown to a peer what is the individual coudchDB limit for the rest of the network. We can design an application to respect certain volume limitations (and that is normal for any software design).
What about if there is a setting (kind of consensus) on the network level for the max doc size? That way we can prevent a bad actor to send a transaction exceeding the limit and therefore breaking the peers of other orgs on the channel. I understand it is about proper configuration. There should be a way though to prevent a bad (or hacked) client from breaking the channel.
@TsvetanG I would be in favor of a channel configuration for max doc size to enforce this upon transaction validation, and also check it during endorsement. To ensure deterministic behavior across peers we would need to enforce it with a new channel application capability, for example it could be enforced starting with V2_5 application capability.
We would need to decide whether it is enforced only for JSON or for any writes (the CouchDB max_document_size applies only to JSON, other data is written as a CouchDB attachment of unlimited size).
While considering this, we should also consider a channel configuration for state database. The docs say not to mix a channel with LevelDB and CouchDB state databases as there are some behavior inconsistencies, but this is not enforced at channel level.
What do you think @manish-sethi ?
Enforcing max doc size behind a new channel capability makes sense. However, the db type setting is more broader settings than the channel level. Ideally, its at the network level. For instance, in the current Fabric design, we cannot allow one channel to specify leveldb and another to specify couchdb as a fabric peer maintains all the channels' state into a single physical database.
Ok, I've updated the issue title to reflect that this issue can be used to add a max doc size channel configuration behind a future application capability. This would prevent the issue of trying to save docs larger than the CouchDB max_document_size configuration.
v2.5 has been released, it could be targeted for v3.0 release in main branch (V3_0 capability) if somebody would like to contribute a pull request.
We discussed in Fabric contributor meeting today. Current thinking is that the check can be done at chaincode execution (endorsement) time rather than at validation time so that a new capability would not be needed.
The following new application property in the channel configuration would be enforced at chaincode execution (endorsement) time:
MaxWriteSize - The maximum bytes for a single key's value in a transaction write set. This roughly corresponds to CouchDB's max_document_size property, which got lowered to a default of 8MB in CouchDB v3. If users are worried about member organizations with a default CouchDB configuration then they could set MaxWriteSize to 8MB. The MaxWriteSize would be enforced for both regular channel data and private data.
If unset in the channel configuration there would be no limit enforced for MaxWriteSize. However, note that there is already an Orderer property "BatchSize.AbsoluteMaxBytes" in the channel configuration to ensure that no single transaction (including all writes in the transaction) is too large, for example to ensure a transaction doesn't consume an inordinate amount of space on peer ledgers (block storage and state database) and to ensure a block doesn't exceed configured gRPC or other network size limits.
On a peer init ( that was working before) I get this error:
And there is no way for this peer to join again to that channel.