ronantakizawa/codereview-bench huggingface dataset:
Repository: codenotary/immudb
File: pkg/server/server.go (Go)

Code before:

// Start starts the immudb server
// Loads and starts the System DB, default db and user db
func (s *ImmuServer) Start() error {
	s.mux.Lock()

	_, err := fmt.Fprintf(os.Stdout, "%s\n%s\n\n", immudbTextLogo, s.Options)
	if err != nil {
		s.Logger.Errorf("Error printing immudb config: %v", err)
	}
	if s.Options.Logfile != "" {
		s.Logger.Infof("\n%s\n%s\n\n", immudbTextLogo, s.Options)
	}
	dataDir := s.Options.Dir
	if err = s.loadDefaultDatabase(dataDir); err != nil {
		s.Logger.Errorf("Unable load default database %s", err)
		return err
	}

	adminPassword, err := auth.DecodeBase64Password(s.Options.AdminPassword)
	if err != nil {
		s.Logger.Errorf(err.Error())
		return err
	}
	if len(adminPassword) == 0 {
		s.Logger.Errorf("Admin password cannot be empty")
		return ErrEmptyAdminPassword
	}

	if err = s.loadSystemDatabase(dataDir, adminPassword); err != nil {
		s.Logger.Errorf("Unable load system database %s", err)
		return err
	}

	if err = s.loadUserDatabases(dataDir); err != nil {
		s.Logger.Errorf("Unable load databases %s", err)
		return err
	}
	s.multidbmode = s.mandatoryAuth()
	if !s.Options.GetAuth() && s.multidbmode {
		s.Logger.Infof("Authentication must be on.")
		return fmt.Errorf("auth should be on")
	}

	options, err := s.setUpMTLS()
	if err != nil {
		s.Logger.Errorf("error setting up MTLS: %s", err)
		return err
	}

	if s.Options.SigningKey != "" {

Review comment (suggestion):
```suggestion
		s.Logger.Errorf(ErrEmptyAdminPassword.Error())
```

Code after:

// Start starts the immudb server
// Loads and starts the System DB, default db and user db
func (s *ImmuServer) Start() error {
	s.mux.Lock()

	_, err := fmt.Fprintf(os.Stdout, "%s\n%s\n\n", immudbTextLogo, s.Options)
	if err != nil {
		s.Logger.Errorf("Error printing immudb config: %v", err)
	}
	if s.Options.Logfile != "" {
		s.Logger.Infof("\n%s\n%s\n\n", immudbTextLogo, s.Options)
	}
	dataDir := s.Options.Dir
	if err = s.loadDefaultDatabase(dataDir); err != nil {
		s.Logger.Errorf("Unable load default database %s", err)
		return err
	}

	adminPassword, err := auth.DecodeBase64Password(s.Options.AdminPassword)
	if err != nil {
		s.Logger.Errorf(err.Error())
		return err
	}
	if len(adminPassword) == 0 {
		s.Logger.Errorf(ErrEmptyAdminPassword.Error())
		return ErrEmptyAdminPassword
	}

	if err = s.loadSystemDatabase(dataDir, adminPassword); err != nil {
		s.Logger.Errorf("Unable load system database %s", err)
		return err
	}

	if err = s.loadUserDatabases(dataDir); err != nil {
		s.Logger.Errorf("Unable load databases %s", err)
		return err
	}
	s.multidbmode = s.mandatoryAuth()
	if !s.Options.GetAuth() && s.multidbmode {
		s.Logger.Infof("Authentication must be on.")
		return fmt.Errorf("auth should be on")
	}

	options, err := s.setUpMTLS()
	if err != nil {
		s.Logger.Errorf("error setting up MTLS: %s", err)
		return err
	}

	if s.Options.SigningKey != "" {
Repository: codenotary/immudb
File: pkg/server/webserver.go (Go)

Code before:
	"github.com/codenotary/immudb/webconsole"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"net/http"
)

func StartWebServer(addr string, tlsConfig *tls.Config, s schema.ImmuServiceServer, l logger.Logger) (*http.Server, error) {
	proxyMux := runtime.NewServeMux()
	err := schema.RegisterImmuServiceHandlerServer(context.Background(), proxyMux, s)
	if err != nil {
		return nil, err
	}

	webMux := http.NewServeMux()
	webMux.Handle("/api/", http.StripPrefix("/api", proxyMux))

	err = webconsole.SetupWebconsole(webMux, l, addr)
	if err != nil {
		return nil, err
	}

	httpServer := &http.Server{Addr: addr, Handler: webMux}
	httpServer.TLSConfig = tlsConfig

	go func() {
		var err error
		if len(tlsConfig.Certificates) > 0 {
			l.Infof("Web API server enabled on %s/api (https)", addr)
			err = httpServer.ListenAndServeTLS("", "")
		} else {
			l.Infof("Web API server enabled on %s/api (http)", addr)
			err = httpServer.ListenAndServe()
		}

		if err == http.ErrServerClosed {
			l.Debugf("Web API/console server closed")
		} else {
			l.Errorf("Web API/console error: %s", err)
		}
	}()

	return httpServer, nil
}


Review comment (suggestion):
Better to check also tlsconfig != Nil in order to avoid a nil pointer error in runtime

Code after:
	"github.com/codenotary/immudb/webconsole"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"net/http"
)

func StartWebServer(addr string, tlsConfig *tls.Config, s schema.ImmuServiceServer, l logger.Logger) (*http.Server, error) {
	proxyMux := runtime.NewServeMux()
	err := schema.RegisterImmuServiceHandlerServer(context.Background(), proxyMux, s)
	if err != nil {
		return nil, err
	}

	webMux := http.NewServeMux()
	webMux.Handle("/api/", http.StripPrefix("/api", proxyMux))

	err = webconsole.SetupWebconsole(webMux, l, addr)
	if err != nil {
		return nil, err
	}

	httpServer := &http.Server{Addr: addr, Handler: webMux}
	httpServer.TLSConfig = tlsConfig

	go func() {
		var err error
		if tlsConfig != nil && len(tlsConfig.Certificates) > 0 {
			l.Infof("Web API server enabled on %s/api (https)", addr)
			err = httpServer.ListenAndServeTLS("", "")
		} else {
			l.Infof("Web API server enabled on %s/api (http)", addr)
			err = httpServer.ListenAndServe()
		}

		if err == http.ErrServerClosed {
			l.Debugf("Web API/console server closed")
		} else {
			l.Errorf("Web API/console error: %s", err)
		}
	}()

	return httpServer, nil
}
Repository: codenotary/immudb
File: webconsole/webconsole_default.go (Go)

Code before:
// +build !webconsole

package webconsole

//go:generate go run github.com/rakyll/statik -f -src=./default -p=webconsole -dest=../ -tags=!webconsole

import (
	"github.com/codenotary/immudb/pkg/logger"
	"net/http"
	"github.com/rakyll/statik/fs"
)

func SetupWebconsole(mux *http.ServeMux, l logger.Logger, addr string) error {
	statikFS, err := fs.New()
	if err != nil {
		return err
	}
	l.Infof("Webconsole not built-in")
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/missing/", http.StatusMovedPermanently)
	})
	mux.Handle("/missing/", http.FileServer(statikFS))
	return nil
}


Review comment (suggestion):
Wouldn't it be better to use some temporary redirect here? Browsers could remember such permanent redirection (including rewriting bookmarks etc) that could be problematic if one wants to switch back to the built-in webconsole.

Code after:
// +build !webconsole

package webconsole

//go:generate go run github.com/rakyll/statik -f -src=./default -p=webconsole -dest=../ -tags=!webconsole

import (
	"github.com/codenotary/immudb/pkg/logger"
	"net/http"
	"github.com/rakyll/statik/fs"
)

func SetupWebconsole(mux *http.ServeMux, l logger.Logger, addr string) error {
	statikFS, err := fs.New()
	if err != nil {
		return err
	}
	l.Infof("Webconsole not built-in")
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/missing/", http.StatusTemporaryRedirect)
	})
	mux.Handle("/missing/", http.FileServer(statikFS))
	return nil
}
Repository: codenotary/immudb
File: cmd/immuclient/command/currentstatus.go (Go)

Code before:
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package immuclient

import (
	"fmt"

	"github.com/spf13/cobra"
)

func (cl *commandline) currentState(cmd *cobra.Command) {
	ccmd := &cobra.Command{
		Use:               "current",
		Short:             "Return the last last tx ID and hash stored locally",
		Aliases:           []string{"crt"},
		PersistentPreRunE: cl.ConfigChain(cl.connect),
		PersistentPostRun: cl.disconnect,
		RunE: func(cmd *cobra.Command, args []string) error {
			resp, err := cl.immucl.CurrentState(args)
			if err != nil {
				cl.quit(err)
			}
			fmt.Fprintf(cmd.OutOrStdout(), resp)
			return nil
		},
		Args: cobra.ExactArgs(0),
	}
	cmd.AddCommand(ccmd)
}


Review comment (bug):
I think your initial approach of having a print function which adds a line break if not already included is good. But I'd do it as simple as possible i.e. adding if the last char is not a line break.
Note: with latest changes a unit testing is failing, probably because the error message differs from what's expected.

Code after:
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package immuclient

import (
	"github.com/spf13/cobra"
)

func (cl *commandline) currentState(cmd *cobra.Command) {
	ccmd := &cobra.Command{
		Use:               "current",
		Short:             "Return the last last tx ID and hash stored locally",
		Aliases:           []string{"crt"},
		PersistentPreRunE: cl.ConfigChain(cl.connect),
		PersistentPostRun: cl.disconnect,
		RunE: func(cmd *cobra.Command, args []string) error {
			resp, err := cl.immucl.CurrentState(args)
			if err != nil {
				cl.quit(err)
			}
			fprintln(cmd.OutOrStdout(), resp)
			return nil
		},
		Args: cobra.ExactArgs(0),
	}
	cmd.AddCommand(ccmd)
}
Repository: codenotary/immudb
File: pkg/server/server_test.go (Go)

Code before:
	md := metadata.Pairs("authorization", lr.Token)
	ctx = metadata.NewIncomingContext(context.Background(), md)

	newdb := &schema.DatabaseSettings{
		DatabaseName: testDatabase,
	}
	_, err = s.CreateDatabase(ctx, newdb)
	if err != nil {
		t.Fatalf("Createdatabase error %v", err)
	}
	err = s.CloseDatabases()
	if err != nil {
		t.Fatalf("closedatabases error %v", err)
	}

	time.Sleep(1 * time.Second)

	if s.dbList.Length() != 2 {
		t.Fatalf("LoadUserDatabase error %d", s.dbList.Length())
	}
}

func testServerSetGet(ctx context.Context, s *ImmuServer, t *testing.T) {
	txMetadata, err := s.Set(ctx, &schema.SetRequest{
		KVs: []*schema.KeyValue{
			{
				Key:   testKey,
				Value: testValue,
			},
		},
	})
	if err != nil {
		t.Fatalf("set error %v", err)
	}

	time.Sleep(1 * time.Millisecond)

	it, err := s.Get(ctx, &schema.KeyRequest{
		Key:     testKey,
		SinceTx: txMetadata.Id,
	})
	if err != nil {
		t.Fatalf("Get error %v", err)
	}
	if it.Tx != txMetadata.Id {
		t.Fatalf("set.get tx missmatch expected %v got %v", txMetadata.Id, it.Tx)
	}
	if !bytes.Equal(it.Key, testKey) {
		t.Fatalf("get key missmatch expected %v got %v", string(testKey), string(it.Key))
	}
	if !bytes.Equal(it.Value, testValue) {

Review comment (bug):
Wouldn't it be better to have a separate dataset just for this failure case?
Simething like `test/data_v1.0.1_dbsettings_test`

Code after:

	md := metadata.Pairs("authorization", lr.Token)
	ctx = metadata.NewIncomingContext(context.Background(), md)

	newdb := &schema.DatabaseSettings{
		DatabaseName: testDatabase,
	}
	_, err = s.CreateDatabase(ctx, newdb)
	if err != nil {
		t.Fatalf("Createdatabase error %v", err)
	}
	err = s.CloseDatabases()
	if err != nil {
		t.Fatalf("closedatabases error %v", err)
	}

	time.Sleep(1 * time.Second)

	if s.dbList.Length() != 2 {
		t.Fatalf("LoadUserDatabase error %d", s.dbList.Length())
	}
}

func TestServerLoadUserDatabases(t *testing.T) {
	copier := fs.NewStandardCopier()
	require.NoError(t, copier.CopyDir("../../test/data_v1.0.1", "data_v1.0.1"))

	defer os.RemoveAll("data_v1.0.1")

	serverOptions := DefaultOptions().WithMetricsServer(false).WithDir("./data_v1.0.1")
	s := DefaultServer().WithOptions(serverOptions).(*ImmuServer)

	s.Initialize()

	err := s.loadUserDatabases(s.Options.Dir, nil)
	require.NoError(t, err)
}

func testServerSetGet(ctx context.Context, s *ImmuServer, t *testing.T) {
	txMetadata, err := s.Set(ctx, &schema.SetRequest{
		KVs: []*schema.KeyValue{
			{
				Key:   testKey,
				Value: testValue,
			},
		},
	})
	if err != nil {
		t.Fatalf("set error %v", err)
	}
Repository: codenotary/immudb
File: pkg/client/auditor/auditor.go (Go)

Code before:
		a.logger.Errorf("audit #%d aborted: %v", a.index, err)
		withError = true
		return noErr
	}

	isEmptyDB := state.TxId == 0

	serverID = a.getServerID(ctx)
	prevState, err = a.history.Get(serverID, dbName)
	if err != nil {
		a.logger.Errorf(err.Error())
		withError = true
		return noErr
	}

	if prevState != nil {
		if isEmptyDB {
			a.logger.Errorf(
				"audit #%d aborted: database is empty on server %s @ %s, "+
					"but locally a previous state exists with hash %x at id %d",
				a.index, serverID, a.serverAddress, prevState.TxHash, prevState.TxId)
			withError = true
			return noErr
		}

		if err := a.verifyStateSignature(serverID, prevState); err != nil {
			a.logger.Errorf("audit #%d aborted: %v", a.index, err)
			withError = true
			return noErr
		}

		vtx, err := a.serviceClient.VerifiableTxById(ctx, &schema.VerifiableTxRequest{
			Tx:           state.TxId,
			ProveSinceTx: prevState.TxId,
		})
		if err != nil {
			a.logger.Errorf(
				"error fetching consistency proof for previous state %d: %v",
				prevState.TxId, err)
			withError = true
			return noErr
		}

		verified = store.VerifyDualProof(
			schema.DualProofFrom(vtx.DualProof),
			prevState.TxId,
			state.TxId,
			schema.DigestFrom(prevState.TxHash),
			schema.DigestFrom(state.TxHash),
		)


Review comment (suggestion):
I think this additional signature verification is not needed. Verifying signature before accepting state evolution should be enough.
Verification of local state will double the amount of signature verifications and will make it harder to deal with changing server signing keys. If verification only happens when a new state is validated, it's easier to deal with a new key by just changing the public key at the auditor.

Code after:
		a.logger.Errorf("audit #%d aborted: %v", a.index, err)
		withError = true
		return noErr
	}

	isEmptyDB := state.TxId == 0

	serverID = a.getServerID(ctx)
	prevState, err = a.history.Get(serverID, dbName)
	if err != nil {
		a.logger.Errorf(err.Error())
		withError = true
		return noErr
	}

	if prevState != nil {
		if isEmptyDB {
			a.logger.Errorf(
				"audit #%d aborted: database is empty on server %s @ %s, "+
					"but locally a previous state exists with hash %x at id %d",
				a.index, serverID, a.serverAddress, prevState.TxHash, prevState.TxId)
			withError = true
			return noErr
		}

		vtx, err := a.serviceClient.VerifiableTxById(ctx, &schema.VerifiableTxRequest{
			Tx:           state.TxId,
			ProveSinceTx: prevState.TxId,
		})
		if err != nil {
			a.logger.Errorf(
				"error fetching consistency proof for previous state %d: %v",
				prevState.TxId, err)
			withError = true
			return noErr
		}

		verified = store.VerifyDualProof(
			schema.DualProofFrom(vtx.DualProof),
			prevState.TxId,
			state.TxId,
			schema.DigestFrom(prevState.TxHash),
			schema.DigestFrom(state.TxHash),
		)

		a.logger.Infof("audit #%d result:\n db: %s, consistent:	%t\n"+
			"  previous state:	%x at tx: %d\n  current state:	%x at tx: %d",
			a.index, dbName, verified,
			prevState.TxHash, prevState.TxId, state.TxHash, state.TxId)

		checked = true
Repository: codenotary/immudb
File: embedded/sql/engine.go (Go)

Code before:
	snapshot       *store.Snapshot
	snapAsBeforeTx uint64

	closed bool

	mutex sync.Mutex
}

func NewEngine(catalogStore, dataStore *store.ImmuStore, prefix []byte) (*Engine, error) {
	if catalogStore == nil || dataStore == nil {
		return nil, ErrIllegalArguments
	}

	e := &Engine{
		catalogStore: catalogStore,
		dataStore:    dataStore,
		prefix:       make([]byte, len(prefix)),
	}

	copy(e.prefix, prefix)

	err := e.LoadCatalog()
	if err != nil {
		return nil, err
	}

	return e, nil
}

// TODO (jeroiraz); this operation won't be needed with a transactional in-memory catalog
func (e *Engine) EnsureCatalogReady() error {
	e.catalogRWMux.Lock()
	defer e.catalogRWMux.Unlock()

	if e.catalog != nil {
		return nil
	}

	return e.LoadCatalog()
}

func (e *Engine) LoadCatalog() error {
	lastTxID, _ := e.catalogStore.Alh()
	err := e.catalogStore.WaitForIndexingUpto(lastTxID, nil)
	if err != nil {
		return err
	}

	latestSnapshot, err := e.catalogStore.SnapshotSince(math.MaxUint64)
	if err != nil {
		return err

Review comment (suggestion):
Not necessarily for this PR but I think we should start passing [`context.Context`](https://pkg.go.dev/context#Context) around - it seems to be the native way to send cancellation requests in golang.

Code after:
	snapshot       *store.Snapshot
	snapAsBeforeTx uint64

	closed bool

	mutex sync.Mutex
}

func NewEngine(catalogStore, dataStore *store.ImmuStore, prefix []byte) (*Engine, error) {
	if catalogStore == nil || dataStore == nil {
		return nil, ErrIllegalArguments
	}

	e := &Engine{
		catalogStore: catalogStore,
		dataStore:    dataStore,
		prefix:       make([]byte, len(prefix)),
	}

	copy(e.prefix, prefix)

	return e, nil
}

// TODO (jeroiraz); this operation won't be needed with a transactional in-memory catalog
func (e *Engine) EnsureCatalogReady(cancellation <-chan struct{}) error {
	e.catalogRWMux.Lock()
	defer e.catalogRWMux.Unlock()

	if e.catalog != nil {
		return nil
	}

	return e.loadCatalog(cancellation)
}

func (e *Engine) ReloadCatalog(cancellation <-chan struct{}) error {
	e.catalogRWMux.Lock()
	defer e.catalogRWMux.Unlock()

	return e.loadCatalog(cancellation)
}

func (e *Engine) loadCatalog(cancellation <-chan struct{}) error {
	lastTxID, _ := e.catalogStore.Alh()
	err := e.catalogStore.WaitForIndexingUpto(lastTxID, cancellation)
	if err != nil {
		return err
	}

	latestSnapshot, err := e.catalogStore.SnapshotSince(math.MaxUint64)
Repository: codenotary/immudb
File: embedded/ahtree/ahtree.go (Go)

Code before:
const cLogEntrySize = offsetSize + szSize
const offsetSize = 8
const szSize = 4

//AHtree stands for Appendable Hash Tree
type AHtree struct {
	pLog appendable.Appendable
	dLog appendable.Appendable
	cLog appendable.Appendable

	pLogSize int64
	dLogSize int64
	cLogSize int64

	pCache *cache.LRUCache
	dCache *cache.LRUCache

	readOnly bool

	closed bool
	mutex  sync.Mutex

	_digests [256 * sha256.Size]byte // pre-allocated array for writing digests
}

func bugOn(cond bool) {
	if cond {
		panic("Unrecoverable bug encountered")
	}
}

func Open(path string, opts *Options) (*AHtree, error) {
	if !validOptions(opts) {
		return nil, ErrIllegalArguments
	}

	finfo, err := os.Stat(path)
	if err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}

		err := os.Mkdir(path, opts.fileMode)
		if err != nil {
			return nil, err
		}
	} else if !finfo.IsDir() {
		return nil, ErrorPathIsNotADirectory
	}

	metadata := appendable.NewMetadata(nil)

Review comment (bug):
Influenced by linux kernel's [`BUG_ON`](https://kernelnewbies.org/FAQ/BUG)

Code after:
const cLogEntrySize = offsetSize + szSize
const offsetSize = 8
const szSize = 4

//AHtree stands for Appendable Hash Tree
type AHtree struct {
	pLog appendable.Appendable
	dLog appendable.Appendable
	cLog appendable.Appendable

	pLogSize int64
	dLogSize int64
	cLogSize int64

	pCache *cache.LRUCache
	dCache *cache.LRUCache

	readOnly bool

	closed bool
	mutex  sync.Mutex

	_digests [256 * sha256.Size]byte // pre-allocated array for writing digests
}

func Open(path string, opts *Options) (*AHtree, error) {
	if !validOptions(opts) {
		return nil, ErrIllegalArguments
	}

	finfo, err := os.Stat(path)
	if err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}

		err := os.Mkdir(path, opts.fileMode)
		if err != nil {
			return nil, err
		}
	} else if !finfo.IsDir() {
		return nil, ErrorPathIsNotADirectory
	}

	metadata := appendable.NewMetadata(nil)
	metadata.PutInt(MetaVersion, Version)

	appendableOpts := multiapp.DefaultOptions().
		WithReadOnly(opts.readOnly).
		WithSynced(opts.synced).
		WithFileSize(opts.fileSize).
Repository: codenotary/immudb
File: pkg/signer/ecdsa_test.go (Go)

Code before:
	ecdsaPK, err := UnmarshalKey(publicKey)
	require.NoError(t, err)
	ok, err := Verify(rawMessage[:], []byte(`wrongsignature`), ecdsaPK)
	assert.False(t, ok)
	assert.Error(t, err)
}

func TestSignature_VerifyFalse(t *testing.T) {
	s, err := NewSigner("./../../test/signer/ec3.key")
	assert.NoError(t, err)
	rawMessage := sha256.Sum256([]byte(`myhash`))
	_, publicKey, _ := s.Sign(rawMessage[:])
	sigToMarshal := ecdsaSignature{R: &big.Int{}, S: &big.Int{}}
	m, _ := asn1.Marshal(sigToMarshal)
	ecdsaPK, err := UnmarshalKey(publicKey)
	require.NoError(t, err)
	ok, err := Verify(rawMessage[:], m, ecdsaPK)
	assert.False(t, ok)
	assert.NoError(t, err)
}

func TestUnmarshalKey_Error(t *testing.T) {
	ecdsaPK, err := UnmarshalKey([]byte(`wrongkey`))
	require.Nil(t, ecdsaPK)
	require.Error(t, err)
	require.Equal(t, "invalid public key", err.Error())
}


Review comment (suggestion):
Once converted to an variable, please check if the error is returned with:

```suggestion
	require.ErrorIs(t, err, ErrInvalidPublicKey)
```

Code after:
	ecdsaPK, err := UnmarshalKey(publicKey)
	require.NoError(t, err)
	ok, err := Verify(rawMessage[:], []byte(`wrongsignature`), ecdsaPK)
	assert.False(t, ok)
	assert.Error(t, err)
}

func TestSignature_VerifyFalse(t *testing.T) {
	s, err := NewSigner("./../../test/signer/ec3.key")
	assert.NoError(t, err)
	rawMessage := sha256.Sum256([]byte(`myhash`))
	_, publicKey, _ := s.Sign(rawMessage[:])
	sigToMarshal := ecdsaSignature{R: &big.Int{}, S: &big.Int{}}
	m, _ := asn1.Marshal(sigToMarshal)
	ecdsaPK, err := UnmarshalKey(publicKey)
	require.NoError(t, err)
	ok, err := Verify(rawMessage[:], m, ecdsaPK)
	assert.False(t, ok)
	assert.NoError(t, err)
}

func TestUnmarshalKey_Error(t *testing.T) {
	ecdsaPK, err := UnmarshalKey([]byte(`wrongkey`))
	require.Nil(t, ecdsaPK)
	require.ErrorIs(t, err, ErrInvalidPublicKey)
}
Repository: codenotary/immudb
File: embedded/store/immustore.go (Go)

Code before:
	txSize += sha256.Size
	copy(s._txbs[txSize:], tx.PrevAlh[:])
	txSize += sha256.Size
	binary.BigEndian.PutUint32(s._txbs[txSize:], uint32(tx.nentries))
	txSize += szSize

	for i := 0; i < tx.nentries; i++ {
		txe := tx.entries[i]
		txe.vOff = offsets[i]

		if txe.constraint != NoConstraint {
			if tx.ID > 1 {
				err := s.WaitForIndexingUpto(tx.ID-1, nil)
				if err != nil {
					return err
				}
			}

			_, _, _, err := s.indexer.Get(txe.Key())
			if err == nil && txe.constraint == MustNotExist {
				return ErrKeyAlreadyExists
			}
			if err == ErrKeyNotFound && txe.constraint == MustExist {
				return ErrKeyNotFound
			}
			if err != ErrKeyNotFound {
				return err
			}
		}

		// tx serialization using pre-allocated buffer
		binary.BigEndian.PutUint32(s._txbs[txSize:], uint32(txe.kLen))
		txSize += szSize
		copy(s._txbs[txSize:], txe.k[:txe.kLen])
		txSize += txe.kLen
		binary.BigEndian.PutUint32(s._txbs[txSize:], uint32(txe.vLen))
		txSize += szSize
		binary.BigEndian.PutUint64(s._txbs[txSize:], uint64(txe.vOff))
		txSize += offsetSize
		copy(s._txbs[txSize:], txe.hVal[:])
		txSize += sha256.Size
	}

	tx.CalcAlh()

	// tx serialization using pre-allocated buffer
	copy(s._txbs[txSize:], tx.Alh[:])
	txSize += sha256.Size

	txbs := make([]byte, txSize)
	copy(txbs, s._txbs[:txSize])

Review comment (suggestion):
Minor: maybe better to move right after `s.indexer.Get` ? That way error checking will be close to the actual method and will be a bit easier to read.

Code after:
	txSize += sha256.Size
	copy(s._txbs[txSize:], tx.PrevAlh[:])
	txSize += sha256.Size
	binary.BigEndian.PutUint32(s._txbs[txSize:], uint32(tx.nentries))
	txSize += szSize

	for i := 0; i < tx.nentries; i++ {
		txe := tx.entries[i]
		txe.vOff = offsets[i]

		if txe.constraint != NoConstraint {
			if tx.ID > 1 {
				err := s.WaitForIndexingUpto(tx.ID-1, nil)
				if err != nil {
					return err
				}
			}

			_, _, _, err := s.indexer.Get(txe.Key())
			if err == nil && txe.constraint == MustNotExist {
				return ErrKeyAlreadyExists
			}
			if err == ErrKeyNotFound && txe.constraint == MustExist {
				return ErrKeyNotFound
			}
			if err != nil && err != ErrKeyNotFound {
				return err
			}
		}

		// tx serialization using pre-allocated buffer
		binary.BigEndian.PutUint32(s._txbs[txSize:], uint32(txe.kLen))
		txSize += szSize
		copy(s._txbs[txSize:], txe.k[:txe.kLen])
		txSize += txe.kLen
		binary.BigEndian.PutUint32(s._txbs[txSize:], uint32(txe.vLen))
		txSize += szSize
		binary.BigEndian.PutUint64(s._txbs[txSize:], uint64(txe.vOff))
		txSize += offsetSize
		copy(s._txbs[txSize:], txe.hVal[:])
		txSize += sha256.Size
	}

	tx.CalcAlh()

	// tx serialization using pre-allocated buffer
	copy(s._txbs[txSize:], tx.Alh[:])
	txSize += sha256.Size

	txbs := make([]byte, txSize)
	copy(txbs, s._txbs[:txSize])