forked from TrueCloudLab/frostfs-contract
[#142] container: panic on missing container
Return more descriptive error message for a user. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
654fc371fd
commit
6bd088aa9f
2 changed files with 101 additions and 12 deletions
|
@ -61,6 +61,9 @@ const (
|
|||
estimateKeyPrefix = "cnr"
|
||||
estimatePostfixSize = 10
|
||||
cleanupDelta = 3
|
||||
|
||||
// NotFoundError is returned if container is missing.
|
||||
NotFoundError = "container does not exist"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -292,13 +295,15 @@ func checkNiceNameAvailable(nnsContractAddr interop.Hash160, domain string) bool
|
|||
// Signature is a RFC6979 signature of container ID.
|
||||
// Token is optional and should be stable marshaled SessionToken structure from
|
||||
// API.
|
||||
//
|
||||
// If a container doesn't exist it panics with NotFoundError.
|
||||
func Delete(containerID []byte, signature interop.Signature, token []byte) {
|
||||
ctx := storage.GetContext()
|
||||
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
|
||||
|
||||
ownerID := getOwnerByID(ctx, containerID)
|
||||
if len(ownerID) == 0 {
|
||||
return
|
||||
if ownerID == nil {
|
||||
panic(NotFoundError)
|
||||
}
|
||||
|
||||
if notaryDisabled {
|
||||
|
@ -345,15 +350,27 @@ func Delete(containerID []byte, signature interop.Signature, token []byte) {
|
|||
// Get method returns structure that contains stable marshaled Container structure,
|
||||
// signature, public key of the container creator and stable marshaled SessionToken
|
||||
// structure if it was provided.
|
||||
//
|
||||
// If a container doesn't exist it panics with NotFoundError.
|
||||
func Get(containerID []byte) Container {
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
return getContainer(ctx, containerID)
|
||||
cnt := getContainer(ctx, containerID)
|
||||
if len(cnt.value) == 0 {
|
||||
panic(NotFoundError)
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
// Owner method returns 25 byte Owner ID of the container.
|
||||
//
|
||||
// If a container doesn't exist it panics with NotFoundError.
|
||||
func Owner(containerID []byte) []byte {
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
return getOwnerByID(ctx, containerID)
|
||||
owner := getOwnerByID(ctx, containerID)
|
||||
if owner == nil {
|
||||
panic(NotFoundError)
|
||||
}
|
||||
return owner
|
||||
}
|
||||
|
||||
// List method returns list of all container IDs owned by specified owner.
|
||||
|
@ -384,6 +401,8 @@ func List(owner []byte) [][]byte {
|
|||
// PublicKey contains public key of the signer.
|
||||
// Token is optional and should be stable marshaled SessionToken structure from
|
||||
// API.
|
||||
//
|
||||
// If a container doesn't exist it panics with NotFoundError.
|
||||
func SetEACL(eACL []byte, signature interop.Signature, publicKey interop.PublicKey, token []byte) {
|
||||
ctx := storage.GetContext()
|
||||
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
|
||||
|
@ -394,8 +413,8 @@ func SetEACL(eACL []byte, signature interop.Signature, publicKey interop.PublicK
|
|||
containerID := eACL[offset : offset+32]
|
||||
|
||||
ownerID := getOwnerByID(ctx, containerID)
|
||||
if len(ownerID) == 0 {
|
||||
panic("container does not exist")
|
||||
if ownerID == nil {
|
||||
panic(NotFoundError)
|
||||
}
|
||||
|
||||
if notaryDisabled {
|
||||
|
@ -439,12 +458,14 @@ func SetEACL(eACL []byte, signature interop.Signature, publicKey interop.PublicK
|
|||
// EACL method returns structure that contains stable marshaled EACLTable structure,
|
||||
// signature, public key of the extended ACL setter and stable marshaled SessionToken
|
||||
// structure if it was provided.
|
||||
//
|
||||
// If a container doesn't exist it panics with NotFoundError.
|
||||
func EACL(containerID []byte) ExtendedACL {
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
|
||||
ownerID := getOwnerByID(ctx, containerID)
|
||||
if len(ownerID) == 0 {
|
||||
panic("container does not exist")
|
||||
if ownerID == nil {
|
||||
panic(NotFoundError)
|
||||
}
|
||||
|
||||
return getEACL(ctx, containerID)
|
||||
|
@ -453,9 +474,15 @@ func EACL(containerID []byte) ExtendedACL {
|
|||
// PutContainerSize method saves container size estimation in contract
|
||||
// memory. Can be invoked only by Storage nodes from the network map. Method
|
||||
// checks witness based on the provided public key of the Storage node.
|
||||
//
|
||||
// If a container doesn't exist it panics with NotFoundError.
|
||||
func PutContainerSize(epoch int, cid []byte, usedSize int, pubKey interop.PublicKey) {
|
||||
ctx := storage.GetContext()
|
||||
|
||||
if getOwnerByID(ctx, cid) == nil {
|
||||
panic(NotFoundError)
|
||||
}
|
||||
|
||||
if !runtime.CheckWitness(pubKey) {
|
||||
panic("invalid witness of container size estimation")
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package tests
|
|||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
|
@ -185,11 +186,62 @@ func TestContainerDelete(t *testing.T) {
|
|||
AddBlockCheckHalt(t, bc, tx)
|
||||
|
||||
tx = PrepareInvoke(t, bc, acc, h, "get", c.id[:])
|
||||
_, err := TestInvoke(bc, tx)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), container.NotFoundError))
|
||||
}
|
||||
|
||||
func TestContainerOwner(t *testing.T) {
|
||||
bc := NewChain(t)
|
||||
h, balanceHash := prepareContainerContract(t, bc)
|
||||
|
||||
acc := NewAccount(t, bc)
|
||||
balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{})
|
||||
|
||||
c := dummyContainer(acc)
|
||||
tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", c.value, c.sig, c.pub, c.token)
|
||||
AddBlockCheckHalt(t, bc, tx)
|
||||
|
||||
t.Run("missing container", func(t *testing.T) {
|
||||
id := c.id
|
||||
id[0] ^= 0xFF
|
||||
tx = PrepareInvoke(t, bc, CommitteeAcc, h, "owner", id[:])
|
||||
_, err := TestInvoke(bc, tx)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), container.NotFoundError))
|
||||
})
|
||||
|
||||
tx = PrepareInvoke(t, bc, CommitteeAcc, h, "owner", c.id[:])
|
||||
owner, _ := base58.Decode(acc.Address)
|
||||
CheckTestInvoke(t, bc, tx, stackitem.NewBuffer(owner))
|
||||
}
|
||||
|
||||
func TestContainerGet(t *testing.T) {
|
||||
bc := NewChain(t)
|
||||
h, balanceHash := prepareContainerContract(t, bc)
|
||||
|
||||
acc := NewAccount(t, bc)
|
||||
balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{})
|
||||
|
||||
c := dummyContainer(acc)
|
||||
tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", c.value, c.sig, c.pub, c.token)
|
||||
AddBlockCheckHalt(t, bc, tx)
|
||||
|
||||
t.Run("missing container", func(t *testing.T) {
|
||||
id := c.id
|
||||
id[0] ^= 0xFF
|
||||
tx = PrepareInvoke(t, bc, CommitteeAcc, h, "get", id[:])
|
||||
_, err := TestInvoke(bc, tx)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), container.NotFoundError))
|
||||
})
|
||||
|
||||
tx = PrepareInvoke(t, bc, CommitteeAcc, h, "get", c.id[:])
|
||||
CheckTestInvoke(t, bc, tx, stackitem.NewStruct([]stackitem.Item{
|
||||
stackitem.NewBuffer([]byte{}),
|
||||
stackitem.NewBuffer([]byte{}),
|
||||
stackitem.NewBuffer([]byte{}),
|
||||
stackitem.NewBuffer([]byte{}),
|
||||
stackitem.NewByteArray(c.value),
|
||||
stackitem.NewByteArray(c.sig),
|
||||
stackitem.NewByteArray(c.pub),
|
||||
stackitem.NewByteArray(c.token),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -222,6 +274,16 @@ func TestContainerSetEACL(t *testing.T) {
|
|||
tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", c.value, c.sig, c.pub, c.token)
|
||||
AddBlockCheckHalt(t, bc, tx)
|
||||
|
||||
t.Run("missing container", func(t *testing.T) {
|
||||
id := c.id
|
||||
id[0] ^= 0xFF
|
||||
e := dummyEACL(id)
|
||||
tx = PrepareInvoke(t, bc, CommitteeAcc, h, "setEACL", e.value, e.sig, e.pub, e.token)
|
||||
_, err := TestInvoke(bc, tx)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), container.NotFoundError))
|
||||
})
|
||||
|
||||
e := dummyEACL(c.id)
|
||||
tx = PrepareInvoke(t, bc, acc, h, "setEACL", e.value, e.sig, e.pub, e.token)
|
||||
AddBlock(t, bc, tx)
|
||||
|
|
Loading…
Reference in a new issue