Hyperledger Fabric - если два обновления происходят почти одновременно, второе отбрасывается - PullRequest
0 голосов
/ 13 марта 2019

Я просто пытаюсь выучить Hyperledger Fabric, и я сделал небольшой тест:

type Valami struct {
        ObjectType string `json:"docType" binding:"required"`
        Value string `json:"value" binding:"required"`
        ID string  `json:"id" binding:"required"`

}

func (t *SimpleChaincode)  test(stub shim.ChaincodeStubInterface)  pb.Response {
        id := "104"
        asbytes, err := stub.GetState(id) //get the marble from chaincode state
        obj := &Valami{}
        if err != nil {
                return shim.Error("Failed to get state ")
        } else if asbytes == nil {
                fmt.Println("not found")
                objtype := "test"
                obj = &Valami{objtype, "", id}

        } else {
                fmt.Println("found")
                err = json.Unmarshal(asbytes, obj)
                if err != nil {
                        return shim.Error("Can not process to a JSON type!")
                }
        }

        now := time.Now()
        value := now.String()
        fmt.Println("value: "+value)
        obj.Value = value


         // update
        JSONasBytes, err := json.Marshal(obj)
        if err != nil {
                return shim.Error("Can not update the " + obj.ID + ". Reason: "+err.Error())
        }
        // save in state
        err = stub.PutState(obj.ID, JSONasBytes)
        if err != nil {
                return shim.Error("Can not save "+ obj.ID + ". Reason: "+err.Error())
        }
        return shim.Success([]byte("value: "+obj.Value))
}

После того, как я выполню это дважды быстро один за другим:

docker exec -e CORE_PEER_LOCALMSPID=Org1MSP -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mur2 -c '{"Args":["test"  ]}'
  docker exec -e CORE_PEER_LOCALMSPID=Org1MSP -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mur2 -c '{"Args":["test"  ]}'

Возвращение:

2019-03-13 09:33:05.297 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 payload:"value: 2019-03-13 09:33:05.292254505 +0000 UTC m=+391.210396576"
2019-03-13 09:33:05.776 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 payload:"value: 2019-03-13 09:33:05.770792084 +0000 UTC m=+391.688934322"

Так что все выглядит хорошо.Однако, когда я проверяю значение:

"{\"docType\":\"test\",\"id\":\"104\",\"value\":\"2019-03-13 09:33:05.292254505 +0000 UTC m=+391.210396576\"}"

Таким образом, фактически второй коммит не встречается.Если я посплю между двумя коммитами, они сработают.Поэтому я думаю, что первый не заканчивается до второго старта, а второй почему-то упал.Я не ожидал этого, потому что это может произойти в любое время в сети.Может ли кто-нибудь объяснить мне, что происходит на заднем плане и как мы можем справиться с такой ситуацией?

Ответы [ 2 ]

2 голосов
/ 13 марта 2019

Простое объяснение: вы не можете обновить один и тот же ключ несколько раз в одном и том же блоке : если вы отправляете несколько транзакций, обновляющих один и тот же ключ, и все транзакции обрабатываются в одном и том же блоке, только одна из них(Я думаю, что первый) будет обработан, а другие транзакции будут отклонены.Вот почему в вашем случае, когда вы отправляете txns очень близко по времени, обрабатывается только один, а если вы добавляете спящий режим между вызовами, оба обрабатываются правильно (спящий режим должен быть равен или больше, чем время вашего блока).Есть несколько способов справиться с этой ситуацией, одним из которых может быть использование очередей и, конечно, разработка внутренней архитектуры таким образом, чтобы минимизировать подобные проблемы.

Обновление:

Разве невозможно установить размер блока равным максимум 1 транзакции?

Невозможно с уверенностью ответить без дальнейшего чтения / исследования.Не уверен насчет последствий с точки зрения стабильности и производительности сети, использующей такую ​​конфигурацию.Здесь есть интересная статья о производительности и оптимизации HLF, написанная год назад (май 2018 года) здесь https://arxiv.org/pdf/1805.11390.pdf, которая может помочь.Может быть, в эти выходные у меня будет время для моих собственных тестов.Дайте мне знать, если вы найдете что-то еще по этой теме, потому что оно мне кажется интересным, хотя я чувствую, что оно не будет работать нормально, потому что сеть имеет собственную задержку, поэтому вы не можете достичь консенсуса почти в 0 раз.

То же самое с Sawtooth?

У вас нет опыта работы с этой платформой, но я думаю, что применима та же идея: блокчейн - это сеть, которой требуется время для достижения консенсуса.о факте, поэтому попытка достичь этого консенсуса за меньшее время, чем внутренняя задержка сети плюс время выполнения алгоритмов консенсуса, ни к чему не приведет.

0 голосов
/ 25 апреля 2019

Это то же самое с Hyperledger Sawtooth?

Нет, это ограничение не распространяется на пилообразную Hyperledger. С Sawtooth вы можете обновлять одну и ту же переменную состояния несколько раз в блоке или в нескольких последовательных транзакциях или даже в одной транзакции. Однако, когда вы делаете это, Sawtooth Validator не может обрабатывать транзакции параллельно. Конфликтующие транзакции (которые работают в одном и том же состоянии) будут обрабатываться последовательно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...