forked from TrueCloudLab/frostfs-contract
[#102] container: Make Put
and Delete
stable for simultaneous invocations in one block
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
c368eac796
commit
98c5fd25c3
1 changed files with 19 additions and 80 deletions
|
@ -43,8 +43,7 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = 1
|
version = 1
|
||||||
ownersKey = "ownersList"
|
|
||||||
|
|
||||||
neofsIDContractKey = "identityScriptHash"
|
neofsIDContractKey = "identityScriptHash"
|
||||||
balanceContractKey = "balanceScriptHash"
|
balanceContractKey = "balanceScriptHash"
|
||||||
|
@ -118,9 +117,7 @@ func Put(container []byte, signature interop.Signature, publicKey interop.Public
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
|
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
|
||||||
|
|
||||||
offset := int(container[1])
|
ownerID := ownerFromBinaryContainer(container)
|
||||||
offset = 2 + offset + 4 // version prefix + version size + owner prefix
|
|
||||||
ownerID := container[offset : offset+25] // offset + size of owner
|
|
||||||
containerID := crypto.Sha256(container)
|
containerID := crypto.Sha256(container)
|
||||||
neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).(interop.Hash160)
|
neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).(interop.Hash160)
|
||||||
cnr := Container{
|
cnr := Container{
|
||||||
|
@ -258,19 +255,10 @@ func List(owner []byte) [][]byte {
|
||||||
|
|
||||||
var list [][]byte
|
var list [][]byte
|
||||||
|
|
||||||
owners := common.GetList(ctx, ownersKey)
|
it := storage.Find(ctx, owner, storage.ValuesOnly)
|
||||||
for i := 0; i < len(owners); i++ {
|
for iterator.Next(it) {
|
||||||
ownerID := owners[i]
|
id := iterator.Value(it).([]byte)
|
||||||
if len(owner) != 0 && !common.BytesEqual(owner, ownerID) {
|
list = append(list, id)
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
containers := common.GetList(ctx, ownerID)
|
|
||||||
|
|
||||||
for j := 0; j < len(containers); j++ {
|
|
||||||
container := containers[j]
|
|
||||||
list = append(list, container)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return list
|
return list
|
||||||
|
@ -511,62 +499,19 @@ func Version() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addContainer(ctx storage.Context, id, owner []byte, container Container) {
|
func addContainer(ctx storage.Context, id, owner []byte, container Container) {
|
||||||
addOrAppend(ctx, ownersKey, owner)
|
containerListKey := append(owner, id...)
|
||||||
addOrAppend(ctx, owner, id)
|
storage.Put(ctx, containerListKey, id)
|
||||||
|
|
||||||
common.SetSerialized(ctx, id, container)
|
common.SetSerialized(ctx, id, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeContainer(ctx storage.Context, id []byte, owner []byte) {
|
func removeContainer(ctx storage.Context, id []byte, owner []byte) {
|
||||||
n := remove(ctx, owner, id)
|
containerListKey := append(owner, id...)
|
||||||
|
storage.Delete(ctx, containerListKey)
|
||||||
// if it was last container, remove owner from the list of owners
|
|
||||||
if n == 0 {
|
|
||||||
_ = remove(ctx, ownersKey, owner)
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.Delete(ctx, id)
|
storage.Delete(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addOrAppend(ctx storage.Context, key interface{}, value []byte) {
|
|
||||||
list := common.GetList(ctx, key)
|
|
||||||
for i := 0; i < len(list); i++ {
|
|
||||||
if common.BytesEqual(list[i], value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(list) == 0 {
|
|
||||||
list = [][]byte{value}
|
|
||||||
} else {
|
|
||||||
list = append(list, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
common.SetSerialized(ctx, key, list)
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove returns amount of left elements in the list
|
|
||||||
func remove(ctx storage.Context, key interface{}, value []byte) int {
|
|
||||||
var (
|
|
||||||
list = common.GetList(ctx, key)
|
|
||||||
newList = [][]byte{}
|
|
||||||
)
|
|
||||||
|
|
||||||
for i := 0; i < len(list); i++ {
|
|
||||||
if !common.BytesEqual(list[i], value) {
|
|
||||||
newList = append(newList, list[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ln := len(newList)
|
|
||||||
if ln == 0 {
|
|
||||||
storage.Delete(ctx, key)
|
|
||||||
} else {
|
|
||||||
common.SetSerialized(ctx, key, newList)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ln
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAllContainers(ctx storage.Context) [][]byte {
|
func getAllContainers(ctx storage.Context) [][]byte {
|
||||||
var list [][]byte
|
var list [][]byte
|
||||||
|
|
||||||
|
@ -600,21 +545,15 @@ func getContainer(ctx storage.Context, cid []byte) Container {
|
||||||
return Container{value: []byte{}, sig: interop.Signature{}, pub: interop.PublicKey{}, token: []byte{}}
|
return Container{value: []byte{}, sig: interop.Signature{}, pub: interop.PublicKey{}, token: []byte{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOwnerByID(ctx storage.Context, id []byte) []byte {
|
func getOwnerByID(ctx storage.Context, cid []byte) []byte {
|
||||||
owners := common.GetList(ctx, ownersKey)
|
container := getContainer(ctx, cid)
|
||||||
for i := 0; i < len(owners); i++ {
|
return ownerFromBinaryContainer(container.value)
|
||||||
ownerID := owners[i]
|
}
|
||||||
containers := common.GetList(ctx, ownerID)
|
|
||||||
|
|
||||||
for j := 0; j < len(containers); j++ {
|
func ownerFromBinaryContainer(container []byte) []byte {
|
||||||
container := containers[j]
|
offset := int(container[1])
|
||||||
if common.BytesEqual(container, id) {
|
offset = 2 + offset + 4 // version prefix + version size + owner prefix
|
||||||
return ownerID
|
return container[offset : offset+25] // offset + size of owner
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func estimationKey(epoch int, cid []byte) []byte {
|
func estimationKey(epoch int, cid []byte) []byte {
|
||||||
|
|
Loading…
Reference in a new issue